已合并
Image and ImageReceiver NDK feature #522
AtomGit-Bot创建于 2023年2月15日
Image and ImageReceiver NDK feature #522
已合并
从refs/pull/522/head合入到master
共 38 个文件变更+2792-889
| @@ -31,6 +31,8 @@ group("image_framework") { | |||
| 31 | } else { | 31 | } else { |
| 32 | deps = [ | 32 | deps = [ |
| 33 | "frameworks/innerkitsimpl/utils:image_utils", | 33 | "frameworks/innerkitsimpl/utils:image_utils", |
| 34 | + "frameworks/kits/js/common/ndk:image_ndk", | ||
| 35 | + "frameworks/kits/js/common/ndk:image_receiver_ndk", | ||
| 34 | "frameworks/kits/js/common/pixelmap_ndk:pixelmap_ndk", | 36 | "frameworks/kits/js/common/pixelmap_ndk:pixelmap_ndk", |
| 35 | "interfaces/innerkits:image_native", | 37 | "interfaces/innerkits:image_native", |
| 36 | "interfaces/kits/js/common:image", | 38 | "interfaces/kits/js/common:image", |
| @@ -83,6 +83,26 @@ | |||
| 83 | ] | 83 | ] |
| 84 | }, | 84 | }, |
| 85 | "name": "//foundation/multimedia/image_framework/frameworks/kits/js/common/pixelmap_ndk:pixelmap_ndk" | 85 | "name": "//foundation/multimedia/image_framework/frameworks/kits/js/common/pixelmap_ndk:pixelmap_ndk" |
| 86 | + }, | ||
| 87 | + { | ||
| 88 | + "header": { | ||
| 89 | + "header_base": "//foundation/multimedia/image_framework/interfaces/kits/native/include/", | ||
| 90 | + "header_files": [ | ||
| 91 | + "image_mdk_common.h", | ||
| 92 | + "image_mdk.h" | ||
| 93 | + ] | ||
| 94 | + }, | ||
| 95 | + "name": "//foundation/multimedia/image_framework/frameworks/kits/js/common/ndk:image_ndk" | ||
| 96 | + }, | ||
| 97 | + { | ||
| 98 | + "header": { | ||
| 99 | + "header_base": "//foundation/multimedia/image_framework/interfaces/kits/native/include/", | ||
| 100 | + "header_files": [ | ||
| 101 | + "image_mdk_common.h", | ||
| 102 | + "image_receiver_mdk.h" | ||
| 103 | + ] | ||
| 104 | + }, | ||
| 105 | + "name": "//foundation/multimedia/image_framework/frameworks/kits/js/common/ndk:image_receiver_ndk" | ||
| 86 | } | 106 | } |
| 87 | ], | 107 | ], |
| 88 | "test": [ | 108 | "test": [ |
| @@ -0,0 +1,340 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (C) 2022 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 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | +using OHOS::HiviewDFX::HiLog; | ||
| 23 | + | ||
| 24 | +namespace { | ||
| 25 | + constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_TAG_DOMAIN_ID_IMAGE, "NativeImage"}; | ||
| 26 | + constexpr int32_t NUMI_0 = 0; | ||
| 27 | + constexpr uint32_t NUM_0 = 0; | ||
| 28 | + constexpr uint32_t NUM_1 = 1; | ||
| 29 | + constexpr uint32_t NUM_2 = 2; | ||
| 30 | + const std::string DATA_SIZE_TAG = "dataSize"; | ||
| 31 | +} | ||
| 32 | + | ||
| 33 | +namespace OHOS { | ||
| 34 | +namespace Media { | ||
| 35 | +NativeImage::NativeImage(sptr<SurfaceBuffer> buffer, | ||
| 36 | + std::shared_ptr<IBufferProcessor> releaser) : buffer_(buffer), releaser_(releaser) | ||
| 37 | +{} | ||
| 38 | + | ||
| 39 | +struct YUVData { | ||
| 40 | + std::vector<uint8_t> y; | ||
| 41 | + std::vector<uint8_t> u; | ||
| 42 | + std::vector<uint8_t> v; | ||
| 43 | + uint64_t ySize; | ||
| 44 | + uint64_t uvSize; | ||
| 45 | +}; | ||
| 46 | + | ||
| 47 | +static inline void DataSwap(uint8_t* a, uint8_t* b, bool flip) | ||
| 48 | +{ | ||
| 49 | + if (flip) { | ||
| 50 | + *a = *b; | ||
| 51 | + } else { | ||
| 52 | + *b = *a; | ||
| 53 | + } | ||
| 54 | +} | ||
| 55 | + | ||
| 56 | +static inline bool IsYUV422SPFormat(int32_t format) | ||
| 57 | +{ | ||
| 58 | + if (format == int32_t(ImageFormat::YCBCR_422_SP) || | ||
| 59 | + format == int32_t(PIXEL_FMT_YCBCR_422_SP)) { | ||
| 60 | + return true; | ||
| 61 | + } | ||
| 62 | + return false; | ||
| 63 | +} | ||
| 64 | + | ||
| 65 | +static void YUV422SPDataCopy(uint8_t* buffer, uint64_t size, YUVData &data, bool flip) | ||
| 66 | +{ | ||
| 67 | + uint64_t ui = NUM_0, vi = NUM_0; | ||
| 68 | + for (uint64_t i = NUM_0; i < size; i++) { | ||
| 69 | + if (i < data.ySize) { | ||
| 70 | + DataSwap(&(buffer[i]), &(data.y[i]), flip); | ||
| 71 | + continue; | ||
| 72 | + } | ||
| 73 | + if (vi >= data.uvSize || ui >= data.uvSize) { | ||
| 74 | + // Over write buffer size. | ||
| 75 | + continue; | ||
| 76 | + } | ||
| 77 | + if (i % NUM_2 == NUM_1) { | ||
| 78 | + DataSwap(&(buffer[i]), &(data.v[vi]), flip); | ||
| 79 | + vi++; | ||
| 80 | + } else { | ||
| 81 | + DataSwap(&(buffer[i]), &(data.u[ui]), flip); | ||
| 82 | + ui++; | ||
| 83 | + } | ||
| 84 | + } | ||
| 85 | +} | ||
| 86 | +uint8_t* NativeImage::GetSurfaceBufferAddr() | ||
| 87 | +{ | ||
| 88 | + if (buffer_ != nullptr) { | ||
| 89 | + return static_cast<uint8_t*>(buffer_->GetVirAddr()); | ||
| 90 | + } | ||
| 91 | + return nullptr; | ||
| 92 | +} | ||
| 93 | +int32_t NativeImage::SplitYUV422SPComponent() | ||
| 94 | +{ | ||
| 95 | + auto rawBuffer = GetSurfaceBufferAddr(); | ||
| 96 | + if (rawBuffer == nullptr) { | ||
| 97 | + HiLog::Error(LABEL, "SurfaceBuffer viraddr is nullptr"); | ||
| 98 | + return ERR_MEDIA_NULL_POINTER; | ||
| 99 | + } | ||
| 100 | + | ||
| 101 | + uint64_t surfaceSize = NUM_0; | ||
| 102 | + auto res = GetDataSize(surfaceSize); | ||
| 103 | + if (res != SUCCESS || surfaceSize == NUM_0) { | ||
| 104 | + HiLog::Error(LABEL, "S size is 0"); | ||
| 105 | + return ERR_MEDIA_DATA_UNSUPPORT; | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | + int32_t width = NUM_0; | ||
| 109 | + int32_t height = NUM_0; | ||
| 110 | + res = GetSize(width, height); | ||
| 111 | + if (res != SUCCESS || width <= NUMI_0 || height <= NUMI_0) { | ||
| 112 | + HiLog::Error(LABEL, "Invaild width %{public}" PRId32 " height %{public}" PRId32, width, height); | ||
| 113 | + return ERR_MEDIA_DATA_UNSUPPORT; | ||
| 114 | + } | ||
| 115 | + | ||
| 116 | + struct YUVData yuv; | ||
| 117 | + uint64_t uvStride = static_cast<uint64_t>((width + NUM_1) / NUM_2); | ||
| 118 | + yuv.ySize = static_cast<uint64_t>(width * height); | ||
| 119 | + yuv.uvSize = static_cast<uint64_t>(height * uvStride); | ||
| 120 | + if (surfaceSize < (yuv.ySize + yuv.uvSize * NUM_2)) { | ||
| 121 | + HiLog::Error(LABEL, "S size %{public}" PRIu64 " < y plane %{public}" PRIu64 | ||
| 122 | + " + uv plane %{public}" PRIu64, surfaceSize, yuv.ySize, yuv.uvSize * NUM_2); | ||
| 123 | + return ERR_MEDIA_DATA_UNSUPPORT; | ||
| 124 | + } | ||
| 125 | + | ||
| 126 | + NativeComponent* y = CreateComponent(int32_t(ComponentType::YUV_Y), yuv.ySize, width, NUM_1, nullptr); | ||
| 127 | + NativeComponent* u = CreateComponent(int32_t(ComponentType::YUV_U), yuv.uvSize, uvStride, NUM_2, nullptr); | ||
| 128 | + NativeComponent* v = CreateComponent(int32_t(ComponentType::YUV_V), yuv.uvSize, uvStride, NUM_2, nullptr); | ||
| 129 | + if ((y == nullptr) || (u == nullptr) || (v == nullptr)) { | ||
| 130 | + HiLog::Error(LABEL, "Create Component failed"); | ||
| 131 | + return ERR_MEDIA_DATA_UNSUPPORT; | ||
| 132 | + } | ||
| 133 | + yuv.y = y->raw; | ||
| 134 | + yuv.u = u->raw; | ||
| 135 | + yuv.v = v->raw; | ||
| 136 | + YUV422SPDataCopy(rawBuffer, surfaceSize, yuv, false); | ||
| 137 | + return SUCCESS; | ||
| 138 | +} | ||
| 139 | + | ||
| 140 | +int32_t NativeImage::SplitSurfaceToComponent() | ||
| 141 | +{ | ||
| 142 | + int32_t format = NUM_0; | ||
| 143 | + auto res = GetFormat(format); | ||
| 144 | + if (res != SUCCESS) { | ||
| 145 | + return res; | ||
| 146 | + } | ||
| 147 | + switch (format) { | ||
| 148 | + case int32_t(ImageFormat::YCBCR_422_SP): | ||
| 149 | + case int32_t(PIXEL_FMT_YCBCR_422_SP): | ||
| 150 | + return SplitYUV422SPComponent(); | ||
| 151 | + case int32_t(ImageFormat::JPEG): | ||
| 152 | + if (CreateCombineComponent(int32_t(ComponentType::JPEG)) != nullptr) { | ||
| 153 | + return SUCCESS; | ||
| 154 | + } | ||
| 155 | + } | ||
| 156 | + // Unsupport split component | ||
| 157 | + return ERR_MEDIA_DATA_UNSUPPORT; | ||
| 158 | +} | ||
| 159 | + | ||
| 160 | +int32_t NativeImage::CombineYUVComponents() | ||
| 161 | +{ | ||
| 162 | + int32_t format = NUM_0; | ||
| 163 | + auto res = GetFormat(format); | ||
| 164 | + if (res != SUCCESS) { | ||
| 165 | + return res; | ||
| 166 | + } | ||
| 167 | + if (!IsYUV422SPFormat(format)) { | ||
| 168 | + HiLog::Info(LABEL, "No need to combine components for NO YUV format now"); | ||
| 169 | + return SUCCESS; | ||
| 170 | + } | ||
| 171 | + | ||
| 172 | + auto y = GetComponent(int32_t(ComponentType::YUV_Y)); | ||
| 173 | + auto u = GetComponent(int32_t(ComponentType::YUV_U)); | ||
| 174 | + auto v = GetComponent(int32_t(ComponentType::YUV_V)); | ||
| 175 | + if ((y == nullptr) || (u == nullptr) || (v == nullptr)) { | ||
| 176 | + HiLog::Error(LABEL, "No component need to combine"); | ||
| 177 | + return ERR_MEDIA_DATA_UNSUPPORT; | ||
| 178 | + } | ||
| 179 | + YUVData data; | ||
| 180 | + data.ySize = y->raw.size(); | ||
| 181 | + data.uvSize = u->raw.size(); | ||
| 182 | + data.y = y->raw; | ||
| 183 | + data.u = u->raw; | ||
| 184 | + data.v = v->raw; | ||
| 185 | + | ||
| 186 | + uint64_t bufferSize = NUM_0; | ||
| 187 | + GetDataSize(bufferSize); | ||
| 188 | + | ||
| 189 | + YUV422SPDataCopy(GetSurfaceBufferAddr(), bufferSize, data, true); | ||
| 190 | + return SUCCESS; | ||
| 191 | +} | ||
| 192 | + | ||
| 193 | +static std::unique_ptr<NativeComponent> BuildComponent(size_t size, int32_t row, int32_t pixel, uint8_t* vir) | ||
| 194 | +{ | ||
| 195 | + if (size == NUM_0 && vir == nullptr) { | ||
| 196 | + HiLog::Error(LABEL, "Could't create 0 size component data"); | ||
| 197 | + return nullptr; | ||
| 198 | + } | ||
| 199 | + std::unique_ptr<NativeComponent> component = std::make_unique<NativeComponent>(); | ||
| 200 | + component->pixelStride = pixel; | ||
| 201 | + component->rowStride = row; | ||
| 202 | + component->size = size; | ||
| 203 | + if (vir != nullptr) { | ||
| 204 | + component->virAddr = vir; | ||
| 205 | + } else { | ||
| 206 | + component->raw.resize(size); | ||
| 207 | + } | ||
| 208 | + return component; | ||
| 209 | +} | ||
| 210 | + | ||
| 211 | +NativeComponent* NativeImage::GetCachedComponent(int32_t type) | ||
| 212 | +{ | ||
| 213 | + auto iter = components_.find(type); | ||
| 214 | + if (iter != components_.end()) { | ||
| 215 | + return iter->second.get(); | ||
| 216 | + } | ||
| 217 | + return nullptr; | ||
| 218 | +} | ||
| 219 | + | ||
| 220 | +NativeComponent* NativeImage::CreateComponent(int32_t type, size_t size, int32_t row, | ||
| 221 | + int32_t pixel, uint8_t* vir) | ||
| 222 | +{ | ||
| 223 | + NativeComponent* res = GetCachedComponent(type); | ||
| 224 | + if (res != nullptr) { | ||
| 225 | + HiLog::Info(LABEL, "Component %{public}d already exist. No need create", type); | ||
| 226 | + return res; | ||
| 227 | + } | ||
| 228 | + | ||
| 229 | + std::unique_ptr<NativeComponent> component = BuildComponent(size, row, pixel, vir); | ||
| 230 | + if (component == nullptr) { | ||
| 231 | + return nullptr; | ||
| 232 | + } | ||
| 233 | + components_.insert(std::map<int32_t, std::unique_ptr<NativeComponent>>::value_type(type, | ||
| 234 | + std::move(component))); | ||
| 235 | + | ||
| 236 | + return GetCachedComponent(type); | ||
| 237 | +} | ||
| 238 | + | ||
| 239 | +NativeComponent* NativeImage::CreateCombineComponent(int32_t type) | ||
| 240 | +{ | ||
| 241 | + uint64_t size = NUM_0; | ||
| 242 | + GetDataSize(size); | ||
| 243 | + return CreateComponent(type, static_cast<size_t>(size), buffer_->GetWidth(), NUM_1, GetSurfaceBufferAddr()); | ||
| 244 | +} | ||
| 245 | +int32_t NativeImage::GetSize(int32_t &width, int32_t &height) | ||
| 246 | +{ | ||
| 247 | + if (buffer_ == nullptr) { | ||
| 248 | + return ERR_MEDIA_DEAD_OBJECT; | ||
| 249 | + } | ||
| 250 | + width = buffer_->GetWidth(); | ||
| 251 | + height = buffer_->GetHeight(); | ||
| 252 | + return SUCCESS; | ||
| 253 | +} | ||
| 254 | + | ||
| 255 | +int32_t NativeImage::GetDataSize(uint64_t &size) | ||
| 256 | +{ | ||
| 257 | + if (buffer_ == nullptr) { | ||
| 258 | + return ERR_MEDIA_DEAD_OBJECT; | ||
| 259 | + } | ||
| 260 | + | ||
| 261 | + size = static_cast<uint64_t>(buffer_->GetSize()); | ||
| 262 | + auto extraData = buffer_->GetExtraData(); | ||
| 263 | + if (extraData == nullptr) { | ||
| 264 | + HiLog::Info(LABEL, "Nullptr s extra data. return buffer size %{public}" PRIu64, size); | ||
| 265 | + return SUCCESS; | ||
| 266 | + } | ||
| 267 | + | ||
| 268 | + int32_t extraDataSize = NUMI_0; | ||
| 269 | + auto res = extraData->ExtraGet(DATA_SIZE_TAG, extraDataSize); | ||
| 270 | + if (res != NUM_0) { | ||
| 271 | + HiLog::Info(LABEL, "S ExtraGet dataSize error %{public}d", res); | ||
| 272 | + } else if (extraDataSize <= NUMI_0) { | ||
| 273 | + HiLog::Info(LABEL, "S ExtraGet dataSize Ok, but size <= 0"); | ||
| 274 | + } else if (static_cast<uint64_t>(extraDataSize) > size) { | ||
| 275 | + HiLog::Info(LABEL, | ||
| 276 | + "S ExtraGet dataSize Ok,but dataSize %{public}d is bigger than bufferSize %{public}" PRIu64, | ||
| 277 | + extraDataSize, size); | ||
| 278 | + } else { | ||
| 279 | + HiLog::Info(LABEL, "S ExtraGet dataSize %{public}d", extraDataSize); | ||
| 280 | + size = extraDataSize; | ||
| 281 | + } | ||
| 282 | + return SUCCESS; | ||
| 283 | +} | ||
| 284 | + | ||
| 285 | +int32_t NativeImage::GetFormat(int32_t &format) | ||
| 286 | +{ | ||
| 287 | + if (buffer_ == nullptr) { | ||
| 288 | + return ERR_MEDIA_DEAD_OBJECT; | ||
| 289 | + } | ||
| 290 | + format = buffer_->GetFormat(); | ||
| 291 | + return SUCCESS; | ||
| 292 | +} | ||
| 293 | + | ||
| 294 | +NativeComponent* NativeImage::GetComponent(int32_t type) | ||
| 295 | +{ | ||
| 296 | + if (buffer_ == nullptr) { | ||
| 297 | + return nullptr; | ||
| 298 | + } | ||
| 299 | + | ||
| 300 | + // Find type if it has exist. | ||
| 301 | + auto component = GetCachedComponent(type); | ||
| 302 | + if (component != nullptr) { | ||
| 303 | + return component; | ||
| 304 | + } | ||
| 305 | + | ||
| 306 | + int32_t format = NUM_0; | ||
| 307 | + if (GetFormat(format) == SUCCESS && type == format) { | ||
| 308 | + return CreateCombineComponent(type); | ||
| 309 | + } | ||
| 310 | + SplitSurfaceToComponent(); | ||
| 311 | + // Try again | ||
| 312 | + component = GetCachedComponent(type); | ||
| 313 | + | ||
| 314 | + | ||
| 315 | + return component; | ||
| 316 | + | ||
| 317 | + if (component == nullptr && GetFormat(format) == SUCCESS) { | ||
| 318 | + return CreateCombineComponent(format); | ||
| 319 | + } | ||
| 320 | + return nullptr; | ||
| 321 | + | ||
| 322 | +} | ||
| 323 | + | ||
| 324 | +void NativeImage::release() | ||
| 325 | +{ | ||
| 326 | + if (buffer_ == nullptr) { | ||
| 327 | + return; | ||
| 328 | + } | ||
| 329 | + HiLog::Info(LABEL, "NativeImage release"); | ||
| 330 | + if (components_.size() > 0) { | ||
| 331 | + components_.clear(); | ||
| 332 | + } | ||
| 333 | + if (releaser_ != nullptr && buffer_ != nullptr) { | ||
| 334 | + releaser_->BufferRelease(buffer_); | ||
| 335 | + } | ||
| 336 | + releaser_ = nullptr; | ||
| 337 | + buffer_ = nullptr; | ||
| 338 | +} | ||
| 339 | +} // namespace Media | ||
| 340 | +} // namespace OHOS | ||
| @@ -30,10 +30,12 @@ | |||
| 30 | 30 | ||
| 31 | 31 | ||
| 32 | 32 | ||
| 33 | - | 33 | +#include "native_image.h" |
| 34 | 34 | ||
| 35 | namespace OHOS { | 35 | namespace OHOS { |
| 36 | namespace Media { | 36 | namespace Media { |
| 37 | +class IBufferProcessor; | ||
| 38 | +class NativeImage; | ||
| 37 | class SurfaceBufferReleaseListener { | 39 | class SurfaceBufferReleaseListener { |
| 38 | public: | 40 | public: |
| 39 | SurfaceBufferReleaseListener()= default; | 41 | SurfaceBufferReleaseListener()= default; |
| @@ -48,14 +50,7 @@ public: | |||
| 48 | std::shared_ptr<SurfaceBufferReleaseListener> surfaceBufferReleaseListener_ = nullptr; | 50 | std::shared_ptr<SurfaceBufferReleaseListener> surfaceBufferReleaseListener_ = nullptr; |
| 49 | std::shared_ptr<SurfaceBufferAvaliableListener> surfaceBufferAvaliableListener_ = nullptr; | 51 | std::shared_ptr<SurfaceBufferAvaliableListener> surfaceBufferAvaliableListener_ = nullptr; |
| 50 | ImageCreator() {}; | 52 | ImageCreator() {}; |
| 51 | - ~ImageCreator() | 53 | + ~ImageCreator(); |
| 52 | - { | ||
| 53 | - creatorConsumerSurface_ = nullptr; | ||
| 54 | - creatorProducerSurface_ = nullptr; | ||
| 55 | - iraContext_ = nullptr; | ||
| 56 | - surfaceBufferReleaseListener_ = nullptr; | ||
| 57 | - surfaceBufferAvaliableListener_ = nullptr; | ||
| 58 | - } | ||
| 59 | void RegisterBufferAvaliableListener( | 54 | void RegisterBufferAvaliableListener( |
| 60 | std::shared_ptr<SurfaceBufferAvaliableListener> surfaceBufferAvaliableListener) | 55 | std::shared_ptr<SurfaceBufferAvaliableListener> surfaceBufferAvaliableListener) |
| 61 | { | 56 | { |
| @@ -85,6 +80,12 @@ public: | |||
| 85 | void ReleaseCreator(); | 80 | void ReleaseCreator(); |
| 86 | static GSError OnBufferRelease(sptr<SurfaceBuffer> &buffer); | 81 | static GSError OnBufferRelease(sptr<SurfaceBuffer> &buffer); |
| 87 | static std::map<uint8_t*, ImageCreator*> bufferCreatorMap_; | 82 | static std::map<uint8_t*, ImageCreator*> bufferCreatorMap_; |
| 83 | + | ||
| 84 | + std::shared_ptr<IBufferProcessor> GetBufferProcessor(); | ||
| 85 | + std::shared_ptr<NativeImage> DequeueNativeImage(); | ||
| 86 | + void QueueNativeImage(std::shared_ptr<NativeImage> image); | ||
| 87 | +private: | ||
| 88 | + std::shared_ptr<IBufferProcessor> bufferProcessor_; | ||
| 88 | }; | 89 | }; |
| 89 | class ImageCreatorSurfaceListener : public IBufferConsumerListener { | 90 | class ImageCreatorSurfaceListener : public IBufferConsumerListener { |
| 90 | public: | 91 | public: |
| @@ -0,0 +1,43 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (C) 2022 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 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | +namespace OHOS { | ||
| 22 | +namespace Media { | ||
| 23 | +class ImageCreatorBufferProcessor : public IBufferProcessor { | ||
| 24 | +public: | ||
| 25 | + explicit ImageCreatorBufferProcessor(ImageCreator* creator) : creator_(creator) | ||
| 26 | + { | ||
| 27 | + } | ||
| 28 | + ~ImageCreatorBufferProcessor() | ||
| 29 | + { | ||
| 30 | + creator_ = nullptr; | ||
| 31 | + } | ||
| 32 | + void BufferRelease(sptr<SurfaceBuffer>& buffer) override | ||
| 33 | + { | ||
| 34 | + // Do not release heare. | ||
| 35 | + (void)buffer; | ||
| 36 | + } | ||
| 37 | +private: | ||
| 38 | + ImageCreator* creator_ = nullptr; | ||
| 39 | +}; | ||
| 40 | +} // namespace Media | ||
| 41 | +} // namespace OHOS | ||
| 42 | + | ||
| 43 | + | ||
| @@ -22,6 +22,7 @@ | |||
| 22 | 22 | ||
| 23 | 23 | ||
| 24 | 24 | ||
| 25 | + | ||
| 25 | 26 | ||
| 26 | namespace OHOS { | 27 | namespace OHOS { |
| 27 | namespace Media { | 28 | namespace Media { |
| @@ -39,9 +40,10 @@ public: | |||
| 39 | string SaveImageCreator(shared_ptr<ImageCreator> imageCreator); | 40 | string SaveImageCreator(shared_ptr<ImageCreator> imageCreator); |
| 40 | sptr<Surface> GetSurfaceByKeyId(string keyId); | 41 | sptr<Surface> GetSurfaceByKeyId(string keyId); |
| 41 | shared_ptr<ImageCreator> GetImageCreatorByKeyId(string keyId); | 42 | shared_ptr<ImageCreator> GetImageCreatorByKeyId(string keyId); |
| 43 | + static void ReleaseCreatorById(string id); | ||
| 42 | private: | 44 | private: |
| 43 | - map<string, shared_ptr<ImageCreator>> mapCreator_; | ||
| 44 | ImageCreatorManager() {}; | 45 | ImageCreatorManager() {}; |
| 46 | + ImageHolderManager<ImageCreator> creatorManager_; | ||
| 45 | }; | 47 | }; |
| 46 | } // namespace Media | 48 | } // namespace Media |
| 47 | } // namespace OHOS | 49 | } // namespace OHOS |
| @@ -18,6 +18,7 @@ | |||
| 18 | 18 | ||
| 19 | 19 | ||
| 20 | 20 | ||
| 21 | + | ||
| 21 | 22 | ||
| 22 | 23 | ||
| 23 | namespace OHOS { | 24 | namespace OHOS { |
| @@ -25,6 +26,17 @@ namespace Media { | |||
| 25 | constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_TAG_DOMAIN_ID_IMAGE, "imageCreator"}; | 26 | constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_TAG_DOMAIN_ID_IMAGE, "imageCreator"}; |
| 26 | std::map<uint8_t*, ImageCreator*> ImageCreator::bufferCreatorMap_; | 27 | std::map<uint8_t*, ImageCreator*> ImageCreator::bufferCreatorMap_; |
| 27 | using namespace OHOS::HiviewDFX; | 28 | using namespace OHOS::HiviewDFX; |
| 29 | +ImageCreator::~ImageCreator() | ||
| 30 | +{ | ||
| 31 | + if (iraContext_ != nullptr) { | ||
| 32 | + ImageCreatorManager::ReleaseCreatorById(iraContext_->GetCreatorKey()); | ||
| 33 | + } | ||
| 34 | + creatorConsumerSurface_ = nullptr; | ||
| 35 | + creatorProducerSurface_ = nullptr; | ||
| 36 | + iraContext_ = nullptr; | ||
| 37 | + surfaceBufferReleaseListener_ = nullptr; | ||
| 38 | + surfaceBufferAvaliableListener_ = nullptr; | ||
| 39 | +} | ||
| 28 | 40 | ||
| 29 | GSError ImageCreator::OnBufferRelease(sptr<SurfaceBuffer> &buffer) | 41 | GSError ImageCreator::OnBufferRelease(sptr<SurfaceBuffer> &buffer) |
| 30 | { | 42 | { |
| @@ -273,10 +285,37 @@ sptr<Surface> ImageCreator::getSurfaceById(std::string id) | |||
| 273 | HiLog::Debug(LABEL, "getSurfaceByCreatorId"); | 285 | HiLog::Debug(LABEL, "getSurfaceByCreatorId"); |
| 274 | return surface; | 286 | return surface; |
| 275 | } | 287 | } |
| 276 | - | ||
| 277 | void ImageCreator::ReleaseCreator() | 288 | void ImageCreator::ReleaseCreator() |
| 278 | { | 289 | { |
| 279 | ImageCreator::~ImageCreator(); | 290 | ImageCreator::~ImageCreator(); |
| 280 | } | 291 | } |
| 292 | + | ||
| 293 | +std::shared_ptr<IBufferProcessor> ImageCreator::GetBufferProcessor() | ||
| 294 | +{ | ||
| 295 | + if (bufferProcessor_ == nullptr) { | ||
| 296 | + bufferProcessor_ = std::make_shared<ImageCreatorBufferProcessor>(this); | ||
| 297 | + } | ||
| 298 | + return bufferProcessor_; | ||
| 299 | +} | ||
| 300 | +std::shared_ptr<NativeImage> ImageCreator::DequeueNativeImage() | ||
| 301 | +{ | ||
| 302 | + if (GetBufferProcessor() == nullptr) { | ||
| 303 | + return nullptr; | ||
| 304 | + } | ||
| 305 | + | ||
| 306 | + auto surfaceBuffer = DequeueImage(); | ||
| 307 | + if (surfaceBuffer == nullptr) { | ||
| 308 | + return nullptr; | ||
| 309 | + } | ||
| 310 | + return std::make_shared<NativeImage>(surfaceBuffer, GetBufferProcessor()); | ||
| 311 | +} | ||
| 312 | +void ImageCreator::QueueNativeImage(std::shared_ptr<NativeImage> image) | ||
| 313 | +{ | ||
| 314 | + if (image == nullptr || image->GetBuffer() == nullptr) { | ||
| 315 | + return; | ||
| 316 | + } | ||
| 317 | + auto buffer = image->GetBuffer(); | ||
| 318 | + QueueImage(buffer); | ||
| 319 | +} | ||
| 281 | } // namespace Media | 320 | } // namespace Media |
| 282 | } // namespace OHOS | 321 | } // namespace OHOS |
| @@ -16,41 +16,27 @@ | |||
| 16 | 16 | ||
| 17 | namespace OHOS { | 17 | namespace OHOS { |
| 18 | namespace Media { | 18 | namespace Media { |
| 19 | -using namespace OHOS::HiviewDFX; | ||
| 20 | using namespace std; | 19 | using namespace std; |
| 21 | string ImageCreatorManager::SaveImageCreator(shared_ptr<ImageCreator> imageCreator) | 20 | string ImageCreatorManager::SaveImageCreator(shared_ptr<ImageCreator> imageCreator) |
| 22 | { | 21 | { |
| 23 | - string id = "1"; | 22 | + return creatorManager_.save(imageCreator); |
| 24 | - | ||
| 25 | - if (GetImageCreatorByKeyId(id) != nullptr) { | ||
| 26 | - mapCreator_.erase(id); | ||
| 27 | - } | ||
| 28 | - | ||
| 29 | - mapCreator_.insert(pair<string, shared_ptr<ImageCreator>>(id, imageCreator)); | ||
| 30 | - return id; | ||
| 31 | } | 23 | } |
| 32 | sptr<Surface> ImageCreatorManager::GetSurfaceByKeyId(string keyId) | 24 | sptr<Surface> ImageCreatorManager::GetSurfaceByKeyId(string keyId) |
| 33 | { | 25 | { |
| 34 | - map<string, shared_ptr<ImageCreator>>::iterator iter; | 26 | + auto creator = GetImageCreatorByKeyId(keyId); |
| 35 | - shared_ptr<ImageCreator> imageCreator = nullptr; | 27 | + if (creator == nullptr) { |
| 36 | - iter = mapCreator_.find(keyId); | ||
| 37 | - if (iter != mapCreator_.end()) { | ||
| 38 | - imageCreator = iter->second; | ||
| 39 | - } | ||
| 40 | - if (imageCreator == nullptr) { | ||
| 41 | return nullptr; | 28 | return nullptr; |
| 42 | } | 29 | } |
| 43 | - return imageCreator->GetCreatorSurface(); | 30 | + return creator->GetCreatorSurface(); |
| 44 | } | 31 | } |
| 45 | shared_ptr<ImageCreator> ImageCreatorManager::GetImageCreatorByKeyId(string keyId) | 32 | shared_ptr<ImageCreator> ImageCreatorManager::GetImageCreatorByKeyId(string keyId) |
| 46 | { | 33 | { |
| 47 | - map<string, shared_ptr<ImageCreator>>::iterator iter; | 34 | + return creatorManager_.get(keyId); |
| 48 | - shared_ptr<ImageCreator> imageCreator = nullptr; | 35 | +} |
| 49 | - iter = mapCreator_.find(keyId); | 36 | +void ImageCreatorManager::ReleaseCreatorById(string id) |
| 50 | - if (iter != mapCreator_.end()) { | 37 | +{ |
| 51 | - imageCreator = iter->second; | 38 | + ImageCreatorManager& manager = ImageCreatorManager::getInstance(); |
| 52 | - } | 39 | + manager.creatorManager_.release(id); |
| 53 | - return imageCreator; | ||
| 54 | } | 40 | } |
| 55 | } // namespace Media | 41 | } // namespace Media |
| 56 | } // namespace OHOS | 42 | } // namespace OHOS |
| @@ -28,9 +28,12 @@ | |||
| 28 | 28 | ||
| 29 | 29 | ||
| 30 | 30 | ||
| 31 | + | ||
| 31 | 32 | ||
| 32 | namespace OHOS { | 33 | namespace OHOS { |
| 33 | namespace Media { | 34 | namespace Media { |
| 35 | +class IBufferProcessor; | ||
| 36 | +class NativeImage; | ||
| 34 | class SurfaceBufferAvaliableListener { | 37 | class SurfaceBufferAvaliableListener { |
| 35 | public: | 38 | public: |
| 36 | SurfaceBufferAvaliableListener()= default; | 39 | SurfaceBufferAvaliableListener()= default; |
| @@ -44,13 +47,7 @@ public: | |||
| 44 | sptr<Surface> receiverProducerSurface_ = nullptr; | 47 | sptr<Surface> receiverProducerSurface_ = nullptr; |
| 45 | std::shared_ptr<SurfaceBufferAvaliableListener> surfaceBufferAvaliableListener_ = nullptr; | 48 | std::shared_ptr<SurfaceBufferAvaliableListener> surfaceBufferAvaliableListener_ = nullptr; |
| 46 | ImageReceiver() {} | 49 | ImageReceiver() {} |
| 47 | - ~ImageReceiver() | 50 | + ~ImageReceiver(); |
| 48 | - { | ||
| 49 | - receiverConsumerSurface_ = nullptr; | ||
| 50 | - receiverProducerSurface_ = nullptr; | ||
| 51 | - iraContext_ = nullptr; | ||
| 52 | - surfaceBufferAvaliableListener_ = nullptr; | ||
| 53 | - } | ||
| 54 | static inline int32_t pipeFd[2] = {}; | 51 | static inline int32_t pipeFd[2] = {}; |
| 55 | static inline std::string OPTION_FORMAT = "image/jpeg"; | 52 | static inline std::string OPTION_FORMAT = "image/jpeg"; |
| 56 | static inline std::int32_t OPTION_QUALITY = 100; | 53 | static inline std::int32_t OPTION_QUALITY = 100; |
| @@ -75,6 +72,12 @@ public: | |||
| 75 | } | 72 | } |
| 76 | static sptr<Surface> getSurfaceById(std::string id); | 73 | static sptr<Surface> getSurfaceById(std::string id); |
| 77 | void ReleaseReceiver(); | 74 | void ReleaseReceiver(); |
| 75 | + | ||
| 76 | + std::shared_ptr<IBufferProcessor> GetBufferProcessor(); | ||
| 77 | + std::shared_ptr<NativeImage> NextNativeImage(); | ||
| 78 | + std::shared_ptr<NativeImage> LastNativeImage(); | ||
| 79 | +private: | ||
| 80 | + std::shared_ptr<IBufferProcessor> bufferProcessor_; | ||
| 78 | }; | 81 | }; |
| 79 | class ImageReceiverSurfaceListener : public IBufferConsumerListener { | 82 | class ImageReceiverSurfaceListener : public IBufferConsumerListener { |
| 80 | public: | 83 | public: |
| @@ -0,0 +1,44 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (C) 2022 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 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | +namespace OHOS { | ||
| 22 | +namespace Media { | ||
| 23 | +class ImageReceiverBufferProcessor : public IBufferProcessor { | ||
| 24 | +public: | ||
| 25 | + explicit ImageReceiverBufferProcessor(ImageReceiver* receiver) : receiver_(receiver) | ||
| 26 | + { | ||
| 27 | + } | ||
| 28 | + ~ImageReceiverBufferProcessor() | ||
| 29 | + { | ||
| 30 | + receiver_ = nullptr; | ||
| 31 | + } | ||
| 32 | + void BufferRelease(sptr<SurfaceBuffer>& buffer) override | ||
| 33 | + { | ||
| 34 | + if (receiver_ != nullptr) { | ||
| 35 | + receiver_->ReleaseBuffer(buffer); | ||
| 36 | + } | ||
| 37 | + } | ||
| 38 | +private: | ||
| 39 | + ImageReceiver* receiver_ = nullptr; | ||
| 40 | +}; | ||
| 41 | +} // namespace Media | ||
| 42 | +} // namespace OHOS | ||
| 43 | + | ||
| 44 | + | ||
| @@ -22,6 +22,7 @@ | |||
| 22 | 22 | ||
| 23 | 23 | ||
| 24 | 24 | ||
| 25 | + | ||
| 25 | 26 | ||
| 26 | namespace OHOS { | 27 | namespace OHOS { |
| 27 | namespace Media { | 28 | namespace Media { |
| @@ -39,9 +40,11 @@ public: | |||
| 39 | string SaveImageReceiver(shared_ptr<ImageReceiver> imageReceiver); | 40 | string SaveImageReceiver(shared_ptr<ImageReceiver> imageReceiver); |
| 40 | sptr<Surface> getSurfaceByKeyId(string keyId); | 41 | sptr<Surface> getSurfaceByKeyId(string keyId); |
| 41 | shared_ptr<ImageReceiver> getImageReceiverByKeyId(string keyId); | 42 | shared_ptr<ImageReceiver> getImageReceiverByKeyId(string keyId); |
| 43 | + static void ReleaseReceiverById(string id); | ||
| 42 | private: | 44 | private: |
| 43 | - map<string, shared_ptr<ImageReceiver>> mapReceiver_; | 45 | + |
| 44 | ImageReceiverManager() {} | 46 | ImageReceiverManager() {} |
| 47 | + ImageHolderManager<ImageReceiver> receiverManager_; | ||
| 45 | }; | 48 | }; |
| 46 | } // namespace Media | 49 | } // namespace Media |
| 47 | } // namespace OHOS | 50 | } // namespace OHOS |
| @@ -18,10 +18,25 @@ | |||
| 18 | 18 | ||
| 19 | 19 | ||
| 20 | 20 | ||
| 21 | + | ||
| 21 | 22 | ||
| 22 | 23 | ||
| 23 | namespace OHOS { | 24 | namespace OHOS { |
| 24 | namespace Media { | 25 | namespace Media { |
| 26 | + ImageReceiver::~ImageReceiver() | ||
| 27 | + { | ||
| 28 | + if (iraContext_ != nullptr) { | ||
| 29 | + ImageReceiverManager::ReleaseReceiverById(iraContext_->GetReceiverKey()); | ||
| 30 | + } | ||
| 31 | + if (receiverConsumerSurface_ != nullptr) { | ||
| 32 | + receiverConsumerSurface_->UnregisterConsumerListener(); | ||
| 33 | + } | ||
| 34 | + receiverConsumerSurface_ = nullptr; | ||
| 35 | + receiverProducerSurface_ = nullptr; | ||
| 36 | + iraContext_ = nullptr; | ||
| 37 | + surfaceBufferAvaliableListener_ = nullptr; | ||
| 38 | + bufferProcessor_ = nullptr; | ||
| 39 | + } | ||
| 25 | constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_TAG_DOMAIN_ID_IMAGE, "imageReceiver"}; | 40 | constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_TAG_DOMAIN_ID_IMAGE, "imageReceiver"}; |
| 26 | using namespace OHOS::HiviewDFX; | 41 | using namespace OHOS::HiviewDFX; |
| 27 | 42 | ||
| @@ -137,7 +152,6 @@ namespace OHOS { | |||
| 137 | buffer = nullptr; | 152 | buffer = nullptr; |
| 138 | } | 153 | } |
| 139 | } | 154 | } |
| 140 | - | ||
| 141 | void ImageReceiverSurfaceListener ::OnBufferAvailable() | 155 | void ImageReceiverSurfaceListener ::OnBufferAvailable() |
| 142 | { | 156 | { |
| 143 | HiLog::Debug(LABEL, "OnBufferAvailable"); | 157 | HiLog::Debug(LABEL, "OnBufferAvailable"); |
| @@ -239,5 +253,38 @@ namespace OHOS { | |||
| 239 | { | 253 | { |
| 240 | ImageReceiver::~ImageReceiver(); | 254 | ImageReceiver::~ImageReceiver(); |
| 241 | } | 255 | } |
| 256 | + | ||
| 257 | +std::shared_ptr<IBufferProcessor> ImageReceiver::GetBufferProcessor() | ||
| 258 | +{ | ||
| 259 | + if (bufferProcessor_ == nullptr) { | ||
| 260 | + bufferProcessor_ = std::make_shared<ImageReceiverBufferProcessor>(this); | ||
| 261 | + } | ||
| 262 | + return bufferProcessor_; | ||
| 263 | +} | ||
| 264 | + | ||
| 265 | +std::shared_ptr<NativeImage> ImageReceiver::NextNativeImage() | ||
| 266 | +{ | ||
| 267 | + if (GetBufferProcessor() == nullptr) { | ||
| 268 | + return nullptr; | ||
| 269 | + } | ||
| 270 | + | ||
| 271 | + auto surfaceBuffer = ReadNextImage(); | ||
| 272 | + if (surfaceBuffer == nullptr) { | ||
| 273 | + return nullptr; | ||
| 274 | + } | ||
| 275 | + return std::make_shared<NativeImage>(surfaceBuffer, GetBufferProcessor()); | ||
| 276 | +} | ||
| 277 | +std::shared_ptr<NativeImage> ImageReceiver::LastNativeImage() | ||
| 278 | +{ | ||
| 279 | + if (GetBufferProcessor() == nullptr) { | ||
| 280 | + return nullptr; | ||
| 281 | + } | ||
| 282 | + | ||
| 283 | + auto surfaceBuffer = ReadLastImage(); | ||
| 284 | + if (surfaceBuffer == nullptr) { | ||
| 285 | + return nullptr; | ||
| 286 | + } | ||
| 287 | + return std::make_shared<NativeImage>(surfaceBuffer, GetBufferProcessor()); | ||
| 288 | +} | ||
| 242 | } // namespace Media | 289 | } // namespace Media |
| 243 | } // namespace OHOS | 290 | } // namespace OHOS |
| @@ -16,41 +16,27 @@ | |||
| 16 | 16 | ||
| 17 | namespace OHOS { | 17 | namespace OHOS { |
| 18 | namespace Media { | 18 | namespace Media { |
| 19 | -using namespace OHOS::HiviewDFX; | ||
| 20 | using namespace std; | 19 | using namespace std; |
| 21 | string ImageReceiverManager::SaveImageReceiver(shared_ptr<ImageReceiver> imageReceiver) | 20 | string ImageReceiverManager::SaveImageReceiver(shared_ptr<ImageReceiver> imageReceiver) |
| 22 | { | 21 | { |
| 23 | - string id = "1"; | 22 | + return receiverManager_.save(imageReceiver); |
| 24 | - | ||
| 25 | - if (getImageReceiverByKeyId(id) != nullptr) { | ||
| 26 | - mapReceiver_.erase(id); | ||
| 27 | - } | ||
| 28 | - | ||
| 29 | - mapReceiver_.insert(pair<string, shared_ptr<ImageReceiver>>(id, imageReceiver)); | ||
| 30 | - return id; | ||
| 31 | -} | ||
| 32 | -sptr<Surface> ImageReceiverManager::getSurfaceByKeyId(string keyId) | ||
| 33 | -{ | ||
| 34 | - map<string, shared_ptr<ImageReceiver>>::iterator iter; | ||
| 35 | - shared_ptr<ImageReceiver> imageReceiver = nullptr; | ||
| 36 | - iter = mapReceiver_.find(keyId); | ||
| 37 | - if (iter != mapReceiver_.end()) { | ||
| 38 | - imageReceiver = iter->second; | ||
| 39 | - } | ||
| 40 | - if (imageReceiver == nullptr) { | ||
| 41 | - return nullptr; | ||
| 42 | - } | ||
| 43 | - return imageReceiver->GetReceiverSurface(); | ||
| 44 | } | 23 | } |
| 45 | shared_ptr<ImageReceiver> ImageReceiverManager::getImageReceiverByKeyId(string keyId) | 24 | shared_ptr<ImageReceiver> ImageReceiverManager::getImageReceiverByKeyId(string keyId) |
| 46 | { | 25 | { |
| 47 | - map<string, shared_ptr<ImageReceiver>>::iterator iter; | 26 | + return receiverManager_.get(keyId); |
| 48 | - shared_ptr<ImageReceiver> imageReceiver = nullptr; | 27 | +} |
| 49 | - iter = mapReceiver_.find(keyId); | 28 | +sptr<Surface> ImageReceiverManager::getSurfaceByKeyId(string keyId) |
| 50 | - if (iter != mapReceiver_.end()) { | 29 | +{ |
| 51 | - imageReceiver = iter->second; | 30 | + shared_ptr<ImageReceiver> imageReceiver = getImageReceiverByKeyId(keyId); |
| 31 | + if (imageReceiver != nullptr) { | ||
| 32 | + return imageReceiver->GetReceiverSurface(); | ||
| 52 | } | 33 | } |
| 53 | - return imageReceiver; | 34 | + return nullptr; |
| 35 | +} | ||
| 36 | +void ImageReceiverManager::ReleaseReceiverById(string id) | ||
| 37 | +{ | ||
| 38 | + ImageReceiverManager& manager = ImageReceiverManager::getInstance(); | ||
| 39 | + manager.receiverManager_.release(id); | ||
| 54 | } | 40 | } |
| 55 | } // namespace Media | 41 | } // namespace Media |
| 56 | } // namespace OHOS | 42 | } // namespace OHOS |
| @@ -0,0 +1,110 @@ | |||
| 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 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | +namespace OHOS { | ||
| 27 | +namespace Media { | ||
| 28 | +template<typename ContentType> | ||
| 29 | +class ImageHolderManager { | ||
| 30 | +public: | ||
| 31 | + ImageHolderManager() {} | ||
| 32 | + ~ImageHolderManager() | ||
| 33 | + { | ||
| 34 | + std::lock_guard<std::mutex> guard(holderMutex_); | ||
| 35 | + holder_.clear(); | ||
| 36 | + } | ||
| 37 | + std::string save(std::shared_ptr<ContentType> content) | ||
| 38 | + { | ||
| 39 | + std::string id; | ||
| 40 | + do { | ||
| 41 | + id = genId(); | ||
| 42 | + } while (exist(id)); | ||
| 43 | + std::lock_guard<std::mutex> guard(holderMutex_); | ||
| 44 | + holder_.insert(std::pair<std::string, std::shared_ptr<ContentType>>(id, content)); | ||
| 45 | + return id; | ||
| 46 | + } | ||
| 47 | + std::shared_ptr<ContentType> get(std::string id) | ||
| 48 | + { | ||
| 49 | + std::lock_guard<std::mutex> guard(holderMutex_); | ||
| 50 | + std::string localId = processEof(id); | ||
| 51 | + auto iter = holder_.find(localId); | ||
| 52 | + if (iter != holder_.end()) { | ||
| 53 | + return iter->second; | ||
| 54 | + } | ||
| 55 | + return nullptr; | ||
| 56 | + } | ||
| 57 | + std::shared_ptr<ContentType> pop(std::string id) | ||
| 58 | + { | ||
| 59 | + std::lock_guard<std::mutex> guard(holderMutex_); | ||
| 60 | + std::string localId = processEof(id); | ||
| 61 | + auto iter = holder_.find(localId); | ||
| 62 | + if (iter != holder_.end()) { | ||
| 63 | + auto res = iter->second; | ||
| 64 | + while (holder_.count(localId)) { | ||
| 65 | + holder_.erase(localId); | ||
| 66 | + } | ||
| 67 | + return res; | ||
| 68 | + } | ||
| 69 | + return nullptr; | ||
| 70 | + } | ||
| 71 | + void release(std::string id) | ||
| 72 | + { | ||
| 73 | + std::lock_guard<std::mutex> guard(holderMutex_); | ||
| 74 | + std::string localId = processEof(id); | ||
| 75 | + while (holder_.count(localId)) { | ||
| 76 | + holder_.erase(localId); | ||
| 77 | + } | ||
| 78 | + } | ||
| 79 | + bool exist(std::string id) | ||
| 80 | + { | ||
| 81 | + std::lock_guard<std::mutex> guard(holderMutex_); | ||
| 82 | + std::string localId = processEof(id); | ||
| 83 | + return holder_.count(localId); | ||
| 84 | + } | ||
| 85 | +private: | ||
| 86 | + std::map<std::string, std::shared_ptr<ContentType>> holder_; | ||
| 87 | + std::mutex idMutex_; | ||
| 88 | + std::mutex holderMutex_; | ||
| 89 | + uint32_t gId_ = 0; | ||
| 90 | + std::string genId() | ||
| 91 | + { | ||
| 92 | + std::lock_guard<std::mutex> guard(idMutex_); | ||
| 93 | + std::string res = std::to_string(gId_); | ||
| 94 | + gId_++; | ||
| 95 | + return res; | ||
| 96 | + } | ||
| 97 | + std::string processEof(std::string id) | ||
| 98 | + { | ||
| 99 | + if (!id.empty() && (id.back() == '\0')) { | ||
| 100 | + std::string tmp = std::string(id); | ||
| 101 | + tmp.pop_back(); | ||
| 102 | + return tmp; | ||
| 103 | + } | ||
| 104 | + return id; | ||
| 105 | + } | ||
| 106 | +}; | ||
| 107 | +} // namespace Media | ||
| 108 | +} // namespace OHOS | ||
| 109 | + | ||
| 110 | + | ||
| @@ -223,15 +223,11 @@ napi_value ImageCreatorNapi::JSCreateImageCreator(napi_env env, napi_callback_in | |||
| 223 | IMAGE_FUNCTION_IN(); | 223 | IMAGE_FUNCTION_IN(); |
| 224 | napi_get_undefined(env, &result); | 224 | napi_get_undefined(env, &result); |
| 225 | status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); | 225 | status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); |
| 226 | - if (status != napi_ok) { | 226 | + if (status != napi_ok || (argc != ARGS4)) { |
| 227 | std::string errMsg = "Invailed arg counts "; | 227 | std::string errMsg = "Invailed arg counts "; |
| 228 | return ImageNapiUtils::ThrowExceptionError(env, static_cast<int32_t>(napi_invalid_arg), | 228 | return ImageNapiUtils::ThrowExceptionError(env, static_cast<int32_t>(napi_invalid_arg), |
| 229 | errMsg.append(std::to_string(argc))); | 229 | errMsg.append(std::to_string(argc))); |
| 230 | } | 230 | } |
| 231 | - if (argc != ARGS4) { | ||
| 232 | - IMAGE_ERR("Invailed arg counts %{public}zu", argc); | ||
| 233 | - return result; | ||
| 234 | - } | ||
| 235 | for (size_t i = PARAM0; i < argc; i++) { | 231 | for (size_t i = PARAM0; i < argc; i++) { |
| 236 | napi_valuetype argvType = ImageNapiUtils::getType(env, argv[i]); | 232 | napi_valuetype argvType = ImageNapiUtils::getType(env, argv[i]); |
| 237 | if (argvType != napi_number) { | 233 | if (argvType != napi_number) { |
| @@ -564,28 +560,29 @@ napi_value ImageCreatorNapi::JsDequeueImage(napi_env env, napi_callback_info inf | |||
| 564 | napi_value result = nullptr; | 560 | napi_value result = nullptr; |
| 565 | napi_get_undefined(env, &result); | 561 | napi_get_undefined(env, &result); |
| 566 | if (g_creatorTest) { | 562 | if (g_creatorTest) { |
| 567 | - result = ImageNapi::Create(env, nullptr); | 563 | + result = ImageNapi::Create(env); |
| 568 | context->status = SUCCESS; | 564 | context->status = SUCCESS; |
| 569 | CommonCallbackRoutine(env, context, result); | 565 | CommonCallbackRoutine(env, context, result); |
| 570 | return; | 566 | return; |
| 571 | } | 567 | } |
| 572 | 568 | ||
| 573 | auto native = context->constructor_->imageCreator_; | 569 | auto native = context->constructor_->imageCreator_; |
| 574 | - if (native == nullptr) { | 570 | + if (native != nullptr) { |
| 575 | - IMAGE_ERR("Native instance is nullptr"); | 571 | + result = ImageNapi::Create(env, native->DequeueNativeImage()); |
| 576 | - context->status = ERR_IMAGE_INIT_ABNORMAL; | 572 | + if (result == nullptr) { |
| 573 | + IMAGE_ERR("ImageNapi Create failed"); | ||
| 574 | + } | ||
| 577 | } else { | 575 | } else { |
| 578 | - auto surfacebuffer = native->DequeueImage(); | 576 | + IMAGE_ERR("Native instance is nullptr"); |
| 579 | - result = ImageNapi::CreateBufferToImage(env, surfacebuffer, native); | ||
| 580 | - if (result == nullptr) { | ||
| 581 | - IMAGE_ERR("ImageNapi Create failed"); | ||
| 582 | - context->status = ERR_IMAGE_INIT_ABNORMAL; | ||
| 583 | - napi_get_undefined(env, &result); | ||
| 584 | - } else { | ||
| 585 | - context->status = SUCCESS; | ||
| 586 | - } | ||
| 587 | } | 577 | } |
| 588 | 578 | ||
| 579 | + if (result == nullptr) { | ||
| 580 | + napi_get_undefined(env, &result); | ||
| 581 | + context->status = ERR_IMAGE_INIT_ABNORMAL; | ||
| 582 | + } else { | ||
| 583 | + context->status = SUCCESS; | ||
| 584 | + } | ||
| 585 | + | ||
| 589 | IMAGE_LINE_OUT(); | 586 | IMAGE_LINE_OUT(); |
| 590 | CommonCallbackRoutine(env, context, result); | 587 | CommonCallbackRoutine(env, context, result); |
| 591 | }; | 588 | }; |
| @@ -593,14 +590,24 @@ napi_value ImageCreatorNapi::JsDequeueImage(napi_env env, napi_callback_info inf | |||
| 593 | return JSCommonProcess(args); | 590 | return JSCommonProcess(args); |
| 594 | } | 591 | } |
| 595 | 592 | ||
| 593 | +static bool IsTestImageArgs(napi_env env, napi_value value) | ||
| 594 | +{ | ||
| 595 | + if (g_creatorTest) { | ||
| 596 | + ImageNapi* image = nullptr; | ||
| 597 | + napi_status status = napi_unwrap(env, value, reinterpret_cast<void**>(&image)); | ||
| 598 | + return (status == napi_ok && image != nullptr); | ||
| 599 | + } | ||
| 600 | + return false; | ||
| 601 | +} | ||
| 602 | + | ||
| 596 | static bool JsQueueArgs(napi_env env, size_t argc, napi_value* argv, | 603 | static bool JsQueueArgs(napi_env env, size_t argc, napi_value* argv, |
| 597 | - std::shared_ptr<ImageNapi> &imageNapi_, napi_ref* callbackRef) | 604 | + std::shared_ptr<NativeImage> &imageNapi_, napi_ref* callbackRef) |
| 598 | { | 605 | { |
| 599 | if (argc == ARGS1 || argc == ARGS2) { | 606 | if (argc == ARGS1 || argc == ARGS2) { |
| 600 | auto argType0 = ImageNapiUtils::getType(env, argv[PARAM0]); | 607 | auto argType0 = ImageNapiUtils::getType(env, argv[PARAM0]); |
| 601 | if (argType0 == napi_object) { | 608 | if (argType0 == napi_object) { |
| 602 | - imageNapi_ = ImageNapi::GetImageSource(env, argv[PARAM0]); | 609 | + imageNapi_ = ImageNapi::GetNativeImage(env, argv[PARAM0]); |
| 603 | - if (imageNapi_ == nullptr) { | 610 | + if (imageNapi_ == nullptr && !IsTestImageArgs(env, argv[PARAM0])) { |
| 604 | ImageNapiUtils::ThrowExceptionError(env, static_cast<int32_t>(napi_invalid_arg), | 611 | ImageNapiUtils::ThrowExceptionError(env, static_cast<int32_t>(napi_invalid_arg), |
| 605 | "Could not get queue type object"); | 612 | "Could not get queue type object"); |
| 606 | return false; | 613 | return false; |
| @@ -645,15 +652,14 @@ void ImageCreatorNapi::JsQueueImageCallBack(napi_env env, napi_status status, | |||
| 645 | } | 652 | } |
| 646 | 653 | ||
| 647 | auto native = context->constructor_->imageCreator_; | 654 | auto native = context->constructor_->imageCreator_; |
| 648 | - if (native == nullptr) { | 655 | + if (native == nullptr || context->imageNapi_ == nullptr) { |
| 649 | IMAGE_ERR("Native instance is nullptr"); | 656 | IMAGE_ERR("Native instance is nullptr"); |
| 650 | context->status = ERR_IMAGE_INIT_ABNORMAL; | 657 | context->status = ERR_IMAGE_INIT_ABNORMAL; |
| 651 | } else { | 658 | } else { |
| 652 | - if (SUCCESS != context->imageNapi_->CombineComponentsIntoSurface()) { | 659 | + if (SUCCESS != context->imageNapi_->CombineYUVComponents()) { |
| 653 | IMAGE_ERR("JsQueueImageCallBack: try to combine componests"); | 660 | IMAGE_ERR("JsQueueImageCallBack: try to combine componests"); |
| 654 | } | 661 | } |
| 655 | - auto surfacebuffer = context->imageNapi_->sSurfaceBuffer_; | 662 | + native->QueueNativeImage(context->imageNapi_); |
| 656 | - native->QueueImage(surfacebuffer); | ||
| 657 | context->status = SUCCESS; | 663 | context->status = SUCCESS; |
| 658 | } | 664 | } |
| 659 | IMAGE_LINE_OUT(); | 665 | IMAGE_LINE_OUT(); |
| @@ -0,0 +1,155 @@ | |||
| 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 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | +namespace { | ||
| 21 | + constexpr uint32_t NUM_0 = 0; | ||
| 22 | +} | ||
| 23 | + | ||
| 24 | +namespace OHOS { | ||
| 25 | +namespace Media { | ||
| 26 | +using ImageNapiEnvFunc = int32_t (*)(napi_env env, struct ImageNapiArgs* args); | ||
| 27 | +using ImageNapiCtxFunc = int32_t (*)(ImageNapi* native, struct ImageNapiArgs* args); | ||
| 28 | + | ||
| 29 | +extern "C" { | ||
| 30 | + | ||
| 31 | + | ||
| 32 | +static NativeImage* GetNativeImage(ImageNapi* napi) | ||
| 33 | +{ | ||
| 34 | + if (napi == nullptr) { | ||
| 35 | + return nullptr; | ||
| 36 | + } | ||
| 37 | + return napi->GetNative(); | ||
| 38 | +} | ||
| 39 | + | ||
| 40 | +static NativeImage* CheckAndGetImage(ImageNapi* native, struct ImageNapiArgs* args) | ||
| 41 | +{ | ||
| 42 | + if (args == nullptr) { | ||
| 43 | + return nullptr; | ||
| 44 | + } | ||
| 45 | + return GetNativeImage(native); | ||
| 46 | +} | ||
| 47 | + | ||
| 48 | +static int32_t ImageNapiClipRect(ImageNapi* native, struct ImageNapiArgs* args) | ||
| 49 | +{ | ||
| 50 | + auto nativeImage = CheckAndGetImage(native, args); | ||
| 51 | + if (nativeImage == nullptr) { | ||
| 52 | + return OHOS_IMAGE_RESULT_BAD_PARAMETER; | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + if (nativeImage->GetSize(args->outRect->width, args->outRect->height) != NUM_0) { | ||
| 56 | + return OHOS_IMAGE_RESULT_BAD_PARAMETER; | ||
| 57 | + } | ||
| 58 | + | ||
| 59 | + args->outRect->x = NUM_0; | ||
| 60 | + args->outRect->y = NUM_0; | ||
| 61 | + return OHOS_IMAGE_RESULT_SUCCESS; | ||
| 62 | +} | ||
| 63 | + | ||
| 64 | +static int32_t ImageNapiSize(ImageNapi* native, struct ImageNapiArgs* args) | ||
| 65 | +{ | ||
| 66 | + auto nativeImage = CheckAndGetImage(native, args); | ||
| 67 | + if (nativeImage == nullptr) { | ||
| 68 | + return OHOS_IMAGE_RESULT_BAD_PARAMETER; | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + if (nativeImage->GetSize(args->outSize->width, args->outSize->height) != NUM_0) { | ||
| 72 | + return OHOS_IMAGE_RESULT_BAD_PARAMETER; | ||
| 73 | + } | ||
| 74 | + return OHOS_IMAGE_RESULT_SUCCESS; | ||
| 75 | +} | ||
| 76 | + | ||
| 77 | +static int32_t ImageNapiFormat(ImageNapi* native, struct ImageNapiArgs* args) | ||
| 78 | +{ | ||
| 79 | + auto nativeImage = CheckAndGetImage(native, args); | ||
| 80 | + if (nativeImage == nullptr) { | ||
| 81 | + return OHOS_IMAGE_RESULT_BAD_PARAMETER; | ||
| 82 | + } | ||
| 83 | + int32_t format; | ||
| 84 | + if (nativeImage->GetFormat(format) != NUM_0) { | ||
| 85 | + return OHOS_IMAGE_RESULT_BAD_PARAMETER; | ||
| 86 | + } | ||
| 87 | + *(args->outNum0) = format; | ||
| 88 | + return OHOS_IMAGE_RESULT_SUCCESS; | ||
| 89 | +} | ||
| 90 | + | ||
| 91 | +static int32_t ImageNapiGetComponent(ImageNapi* native, struct ImageNapiArgs* args) | ||
| 92 | +{ | ||
| 93 | + auto nativeImage = CheckAndGetImage(native, args); | ||
| 94 | + if (nativeImage == nullptr || args->outComponent == nullptr) { | ||
| 95 | + return OHOS_IMAGE_RESULT_BAD_PARAMETER; | ||
| 96 | + } | ||
| 97 | + | ||
| 98 | + auto nativeComponent = nativeImage->GetComponent(args->inNum0); | ||
| 99 | + if (nativeComponent == nullptr || nativeComponent->size == NUM_0) { | ||
| 100 | + return OHOS_IMAGE_RESULT_BAD_PARAMETER; | ||
| 101 | + } | ||
| 102 | + | ||
| 103 | + if (nativeComponent->virAddr != nullptr) { | ||
| 104 | + args->outComponent->byteBuffer = nativeComponent->virAddr; | ||
| 105 | + } else { | ||
| 106 | + args->outComponent->byteBuffer = nativeComponent->raw.data(); | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | + if (args->outComponent->byteBuffer == nullptr) { | ||
| 110 | + return OHOS_IMAGE_RESULT_BAD_PARAMETER; | ||
| 111 | + } | ||
| 112 | + args->outComponent->size = nativeComponent->size; | ||
| 113 | + args->outComponent->componentType = args->inNum0; | ||
| 114 | + args->outComponent->pixelStride = nativeComponent->pixelStride; | ||
| 115 | + args->outComponent->rowStride = nativeComponent->rowStride; | ||
| 116 | + return OHOS_IMAGE_RESULT_SUCCESS; | ||
| 117 | +} | ||
| 118 | + | ||
| 119 | +static const std::map<int32_t, ImageNapiCtxFunc> g_CtxFunctions = { | ||
| 120 | + {CTX_FUNC_IMAGE_CLIP_RECT, ImageNapiClipRect}, | ||
| 121 | + {CTX_FUNC_IMAGE_SIZE, ImageNapiSize}, | ||
| 122 | + {CTX_FUNC_IMAGE_FORMAT, ImageNapiFormat}, | ||
| 123 | + {CTX_FUNC_IMAGE_GET_COMPONENT, ImageNapiGetComponent}, | ||
| 124 | +}; | ||
| 125 | + | ||
| 126 | +MIDK_EXPORT | ||
| 127 | +int32_t ImageNapiNativeCtxCall(int32_t mode, ImageNapi* native, struct ImageNapiArgs* args) | ||
| 128 | +{ | ||
| 129 | + auto funcSearch = g_CtxFunctions.find(mode); | ||
| 130 | + if (funcSearch == g_CtxFunctions.end()) { | ||
| 131 | + return OHOS_IMAGE_RESULT_BAD_PARAMETER; | ||
| 132 | + } | ||
| 133 | + return funcSearch->second(native, args); | ||
| 134 | +} | ||
| 135 | + | ||
| 136 | +MIDK_EXPORT | ||
| 137 | +ImageNapi* ImageNapi_Unwrap(napi_env env, napi_value value) | ||
| 138 | +{ | ||
| 139 | + napi_valuetype valueType; | ||
| 140 | + napi_typeof(env, value, &valueType); | ||
| 141 | + if (valueType != napi_object) { | ||
| 142 | + return nullptr; | ||
| 143 | + } | ||
| 144 | + std::unique_ptr<ImageNapi> imageNapi = nullptr; | ||
| 145 | + napi_status status = napi_unwrap(env, value, reinterpret_cast<void**>(&imageNapi)); | ||
| 146 | + if ((status == napi_ok) && imageNapi != nullptr) { | ||
| 147 | + return imageNapi.release(); | ||
| 148 | + } | ||
| 149 | + return nullptr; | ||
| 150 | +} | ||
| 151 | + | ||
| 152 | +}; | ||
| 153 | + | ||
| 154 | +} // namespace Media | ||
| 155 | +} // namespace OHOS | ||
| @@ -14,240 +14,53 @@ | |||
| 14 | */ | 14 | */ |
| 15 | 15 | ||
| 16 | 16 | ||
| 17 | -#include "media_errors.h" | 17 | + |
| 18 | + | ||
| 18 | 19 | ||
| 20 | + | ||
| 19 | 21 | ||
| 20 | 22 | ||
| 21 | 23 | ||
| 22 | -using OHOS::HiviewDFX::HiLog; | ||
| 23 | -using std::string; | ||
| 24 | -using std::shared_ptr; | ||
| 25 | -using std::unique_ptr; | ||
| 26 | -using std::vector; | ||
| 27 | -using std::make_shared; | ||
| 28 | -using std::make_unique; | ||
| 29 | - | ||
| 30 | namespace { | 24 | namespace { |
| 31 | constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "ImageNapi"}; | 25 | constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "ImageNapi"}; |
| 26 | + constexpr int NUM0 = 0; | ||
| 27 | + constexpr int NUM1 = 1; | ||
| 28 | + constexpr int NUM2 = 2; | ||
| 29 | + const std::string MY_NAME = "ImageNapi"; | ||
| 32 | } | 30 | } |
| 33 | 31 | ||
| 34 | namespace OHOS { | 32 | namespace OHOS { |
| 35 | namespace Media { | 33 | namespace Media { |
| 36 | -static const std::string CLASS_NAME = "ImageNapi"; | 34 | +using OHOS::HiviewDFX::HiLog; |
| 37 | -static const std::string SURFACE_DATA_SIZE_TAG = "dataSize"; | 35 | +struct ImageAsyncContext { |
| 38 | -std::shared_ptr<ImageReceiver> ImageNapi::staticImageReceiverInstance_ = nullptr; | 36 | + napi_env env = nullptr; |
| 39 | -std::shared_ptr<ImageCreator> ImageNapi::staticImageCreatorInstance_ = nullptr; | 37 | + napi_async_work work = nullptr; |
| 40 | -sptr<SurfaceBuffer> ImageNapi::staticInstance_ = nullptr; | 38 | + napi_deferred deferred = nullptr; |
| 39 | + napi_ref callbackRef = nullptr; | ||
| 40 | + napi_ref thisRef = nullptr; | ||
| 41 | + ImageNapi *napi = nullptr; | ||
| 42 | + uint32_t status; | ||
| 43 | + int32_t componentType; | ||
| 44 | + NativeImage* image = nullptr; | ||
| 45 | + NativeComponent* component = nullptr; | ||
| 46 | + bool isTestContext = false; | ||
| 47 | +}; | ||
| 48 | +ImageHolderManager<NativeImage> ImageNapi::sNativeImageHolder_; | ||
| 41 | thread_local napi_ref ImageNapi::sConstructor_ = nullptr; | 49 | thread_local napi_ref ImageNapi::sConstructor_ = nullptr; |
| 42 | -static bool g_receiverTest = false; | ||
| 43 | 50 | ||
| 44 | -const int ARGS0 = 0; | 51 | +ImageNapi::ImageNapi() |
| 45 | -const int ARGS1 = 1; | ||
| 46 | -const int ARGS2 = 2; | ||
| 47 | -const int PARAM0 = 0; | ||
| 48 | -const int PARAM1 = 1; | ||
| 49 | -const int PARAM2 = 2; | ||
| 50 | -const int NUM0 = 0; | ||
| 51 | -const int NUM1 = 1; | ||
| 52 | -const int NUM2 = 2; | ||
| 53 | - | ||
| 54 | -ImageNapi::ImageNapi():env_(nullptr) | ||
| 55 | {} | 52 | {} |
| 56 | 53 | ||
| 57 | ImageNapi::~ImageNapi() | 54 | ImageNapi::~ImageNapi() |
| 58 | { | 55 | { |
| 59 | - release(); | 56 | + NativeRelease(); |
| 60 | -} | ||
| 61 | -struct YUV422SPData { | ||
| 62 | - std::vector<uint8_t> y; | ||
| 63 | - std::vector<uint8_t> u; | ||
| 64 | - std::vector<uint8_t> v; | ||
| 65 | - uint64_t ySize; | ||
| 66 | - uint64_t uvSize; | ||
| 67 | -}; | ||
| 68 | - | ||
| 69 | - | ||
| 70 | -static void YUV422SPDataCopy(uint8_t* surfaceBuffer, uint64_t bufferSize, | ||
| 71 | - YUV422SPData &data, bool flip) | ||
| 72 | -{ | ||
| 73 | - uint64_t ui = NUM0, vi = NUM0; | ||
| 74 | - for (uint64_t i = NUM0; i < bufferSize; i++) { | ||
| 75 | - if (i < data.ySize) { | ||
| 76 | - if (flip) { | ||
| 77 | - surfaceBuffer[i] = data.y[i]; | ||
| 78 | - } else { | ||
| 79 | - data.y[i] = surfaceBuffer[i]; | ||
| 80 | - } | ||
| 81 | - continue; | ||
| 82 | - } | ||
| 83 | - if (vi >= data.uvSize || ui >= data.uvSize) { | ||
| 84 | - // Over write buffer size. | ||
| 85 | - continue; | ||
| 86 | - } | ||
| 87 | - if (i % NUM2 == NUM1) { | ||
| 88 | - if (flip) { | ||
| 89 | - surfaceBuffer[i] = data.v[vi++]; | ||
| 90 | - } else { | ||
| 91 | - data.v[vi++] = surfaceBuffer[i]; | ||
| 92 | - } | ||
| 93 | - } else { | ||
| 94 | - if (flip) { | ||
| 95 | - surfaceBuffer[i] = data.u[ui++]; | ||
| 96 | - } else { | ||
| 97 | - data.u[ui++] = surfaceBuffer[i]; | ||
| 98 | - } | ||
| 99 | - } | ||
| 100 | - } | ||
| 101 | -} | ||
| 102 | - | ||
| 103 | -static uint64_t GetSurfaceDataSize(sptr<SurfaceBuffer> surface) | ||
| 104 | -{ | ||
| 105 | - if (surface == nullptr) { | ||
| 106 | - HiLog::Error(LABEL, "Nullptr surface"); | ||
| 107 | - return NUM0; | ||
| 108 | - } | ||
| 109 | - | ||
| 110 | - uint64_t bufferSize = surface->GetSize(); | ||
| 111 | - auto surfaceExtraData = surface->GetExtraData(); | ||
| 112 | - if (surfaceExtraData == nullptr) { | ||
| 113 | - HiLog::Error(LABEL, "Nullptr surface extra data. return buffer size %{public}" PRIu64, bufferSize); | ||
| 114 | - return bufferSize; | ||
| 115 | - } | ||
| 116 | - | ||
| 117 | - int32_t extraDataSize = NUM0; | ||
| 118 | - auto res = surfaceExtraData->ExtraGet(SURFACE_DATA_SIZE_TAG, extraDataSize); | ||
| 119 | - if (res != NUM0) { | ||
| 120 | - HiLog::Error(LABEL, "Surface ExtraGet dataSize error %{public}d", res); | ||
| 121 | - return bufferSize; | ||
| 122 | - } else if (extraDataSize <= NUM0) { | ||
| 123 | - HiLog::Error(LABEL, "Surface ExtraGet dataSize Ok, but size <= 0"); | ||
| 124 | - return bufferSize; | ||
| 125 | - } else if (static_cast<uint64_t>(extraDataSize) > bufferSize) { | ||
| 126 | - HiLog::Error(LABEL, | ||
| 127 | - "Surface ExtraGet dataSize Ok,but dataSize %{public}d is bigger than bufferSize %{public}" PRIu64, | ||
| 128 | - extraDataSize, bufferSize); | ||
| 129 | - return bufferSize; | ||
| 130 | - } | ||
| 131 | - HiLog::Info(LABEL, "Surface ExtraGet dataSize %{public}d", extraDataSize); | ||
| 132 | - return extraDataSize; | ||
| 133 | -} | ||
| 134 | - | ||
| 135 | -static uint32_t ProcessYUV422SP(ImageNapi* imageNapi, sptr<SurfaceBuffer> surface) | ||
| 136 | -{ | ||
| 137 | - IMAGE_FUNCTION_IN(); | ||
| 138 | - uint8_t* surfaceBuffer = static_cast<uint8_t*>(surface->GetVirAddr()); | ||
| 139 | - if (surfaceBuffer == nullptr) { | ||
| 140 | - HiLog::Error(LABEL, "Nullptr surface buffer"); | ||
| 141 | - return ERR_IMAGE_DATA_ABNORMAL; | ||
| 142 | - } | ||
| 143 | - uint64_t surfaceSize = GetSurfaceDataSize(surface); | ||
| 144 | - if (surfaceSize == NUM0) { | ||
| 145 | - HiLog::Error(LABEL, "Surface size is 0"); | ||
| 146 | - return ERR_IMAGE_DATA_ABNORMAL; | ||
| 147 | - } | ||
| 148 | - if (surface->GetHeight() <= NUM0 || surface->GetWidth() <= NUM0) { | ||
| 149 | - HiLog::Error(LABEL, "Invaild width %{public}" PRId32 " height %{public}" PRId32, | ||
| 150 | - surface->GetWidth(), surface->GetHeight()); | ||
| 151 | - return ERR_IMAGE_DATA_ABNORMAL; | ||
| 152 | - } | ||
| 153 | - uint64_t ySize = static_cast<uint64_t>(surface->GetHeight() * surface->GetWidth()); | ||
| 154 | - uint64_t uvStride = static_cast<uint64_t>((surface->GetWidth() + NUM1) / NUM2); | ||
| 155 | - uint64_t uvSize = static_cast<uint64_t>(surface->GetHeight() * uvStride); | ||
| 156 | - if (surfaceSize < (ySize + uvSize * NUM2)) { | ||
| 157 | - HiLog::Error(LABEL, "Surface size %{public}" PRIu64 " < y plane %{public}" PRIu64 | ||
| 158 | - " + uv plane %{public}" PRIu64, surfaceSize, ySize, uvSize * NUM2); | ||
| 159 | - return ERR_IMAGE_DATA_ABNORMAL; | ||
| 160 | - } | ||
| 161 | - | ||
| 162 | - Component* y = imageNapi->CreateComponentData(ComponentType::YUV_Y, ySize, surface->GetWidth(), NUM1); | ||
| 163 | - Component* u = imageNapi->CreateComponentData(ComponentType::YUV_U, uvSize, uvStride, NUM2); | ||
| 164 | - Component* v = imageNapi->CreateComponentData(ComponentType::YUV_V, uvSize, uvStride, NUM2); | ||
| 165 | - if ((y == nullptr) || (u == nullptr) || (v == nullptr)) { | ||
| 166 | - HiLog::Error(LABEL, "Create Component failed"); | ||
| 167 | - return ERR_IMAGE_DATA_ABNORMAL; | ||
| 168 | - } | ||
| 169 | - struct YUV422SPData data; | ||
| 170 | - data.ySize = ySize; | ||
| 171 | - data.uvSize = uvSize; | ||
| 172 | - data.y = y->raw; | ||
| 173 | - data.u = u->raw; | ||
| 174 | - data.v = v->raw; | ||
| 175 | - YUV422SPDataCopy(surfaceBuffer, surfaceSize, data, false); | ||
| 176 | - return SUCCESS; | ||
| 177 | -} | ||
| 178 | -static uint32_t SplitSurfaceToComponent(ImageNapi* imageNapi, sptr<SurfaceBuffer> surface) | ||
| 179 | -{ | ||
| 180 | - auto surfaceFormat = surface->GetFormat(); | ||
| 181 | - switch (surfaceFormat) { | ||
| 182 | - case int32_t(ImageFormat::YCBCR_422_SP): | ||
| 183 | - case int32_t(PIXEL_FMT_YCBCR_422_SP): | ||
| 184 | - return ProcessYUV422SP(imageNapi, surface); | ||
| 185 | - default: | ||
| 186 | - break; | ||
| 187 | - } | ||
| 188 | - // Unsupport split component | ||
| 189 | - return ERR_IMAGE_DATA_UNSUPPORT; | ||
| 190 | -} | ||
| 191 | - | ||
| 192 | -static void CommonCallbackRoutine(napi_env env, ImageAsyncContext* &context, | ||
| 193 | - const napi_value &valueParam) | ||
| 194 | -{ | ||
| 195 | - IMAGE_FUNCTION_IN(); | ||
| 196 | - napi_value result[2] = {0}; | ||
| 197 | - napi_value retVal; | ||
| 198 | - napi_value callback = nullptr; | ||
| 199 | - | ||
| 200 | - napi_get_undefined(env, &result[0]); | ||
| 201 | - napi_get_undefined(env, &result[1]); | ||
| 202 | - | ||
| 203 | - if (context == nullptr) { | ||
| 204 | - IMAGE_ERR("context is nullptr"); | ||
| 205 | - return; | ||
| 206 | - } | ||
| 207 | - | ||
| 208 | - if (context->status == SUCCESS) { | ||
| 209 | - result[1] = valueParam; | ||
| 210 | - } | ||
| 211 | - | ||
| 212 | - if (context->deferred) { | ||
| 213 | - if (context->status == SUCCESS) { | ||
| 214 | - napi_resolve_deferred(env, context->deferred, result[1]); | ||
| 215 | - } else { | ||
| 216 | - ImageNapiUtils::CreateErrorObj(env, result[0], context->status, | ||
| 217 | - "There is generic napi failure!"); | ||
| 218 | - napi_reject_deferred(env, context->deferred, result[0]); | ||
| 219 | - } | ||
| 220 | - } else { | ||
| 221 | - if (context->status == SUCCESS) { | ||
| 222 | - napi_create_uint32(env, context->status, &result[0]); | ||
| 223 | - } else { | ||
| 224 | - ImageNapiUtils::CreateErrorObj(env, result[0], context->status, | ||
| 225 | - "There is generic napi failure!"); | ||
| 226 | - } | ||
| 227 | - napi_get_reference_value(env, context->callbackRef, &callback); | ||
| 228 | - napi_call_function(env, nullptr, callback, PARAM2, result, &retVal); | ||
| 229 | - napi_delete_reference(env, context->callbackRef); | ||
| 230 | - } | ||
| 231 | - | ||
| 232 | - napi_delete_async_work(env, context->work); | ||
| 233 | - | ||
| 234 | - delete context; | ||
| 235 | - context = nullptr; | ||
| 236 | - IMAGE_FUNCTION_OUT(); | ||
| 237 | } | 57 | } |
| 238 | 58 | ||
| 239 | void ImageNapi::NativeRelease() | 59 | void ImageNapi::NativeRelease() |
| 240 | { | 60 | { |
| 241 | - if (imageReceiver_ != nullptr) { | 61 | + if (native_ != nullptr) { |
| 242 | - imageReceiver_->ReleaseBuffer(sSurfaceBuffer_); | 62 | + native_->release(); |
| 243 | - imageReceiver_ = nullptr; | 63 | + native_ = nullptr; |
| 244 | - } | ||
| 245 | - sSurfaceBuffer_ = nullptr; | ||
| 246 | - if (componentData_.size() > 0) { | ||
| 247 | - for (auto iter = componentData_.begin(); iter != componentData_.end(); iter++) { | ||
| 248 | - iter->second = nullptr; | ||
| 249 | - componentData_.erase(iter); | ||
| 250 | - } | ||
| 251 | } | 64 | } |
| 252 | } | 65 | } |
| 253 | 66 | ||
| @@ -261,197 +74,264 @@ napi_value ImageNapi::Init(napi_env env, napi_value exports) | |||
| 261 | DECLARE_NAPI_FUNCTION("getComponent", JsGetComponent), | 74 | DECLARE_NAPI_FUNCTION("getComponent", JsGetComponent), |
| 262 | DECLARE_NAPI_FUNCTION("release", JsRelease), | 75 | DECLARE_NAPI_FUNCTION("release", JsRelease), |
| 263 | }; | 76 | }; |
| 264 | - napi_value constructor = nullptr; | 77 | + size_t size = IMG_ARRAY_SIZE(props); |
| 78 | + napi_value thisVar = nullptr; | ||
| 79 | + auto name = MY_NAME.c_str(); | ||
| 80 | + if (napi_define_class(env, name, SIZE_MAX, Constructor, nullptr, size, props, &thisVar) != napi_ok) { | ||
| 81 | + IMAGE_ERR("Define class failed"); | ||
| 82 | + return exports; | ||
| 83 | + } | ||
| 265 | 84 | ||
| 266 | - IMG_NAPI_CHECK_RET_D(IMG_IS_OK( | 85 | + if (sConstructor_ != nullptr) { |
| 267 | - napi_define_class(env, CLASS_NAME.c_str(), NAPI_AUTO_LENGTH, Constructor, | 86 | + napi_delete_reference(env, sConstructor_); |
| 268 | - nullptr, IMG_ARRAY_SIZE(props), props, &constructor)), | 87 | + sConstructor_ = nullptr; |
| 269 | - nullptr, | 88 | + } |
| 270 | - IMAGE_ERR("define class fail") | ||
| 271 | - ); | ||
| 272 | 89 | ||
| 273 | - IMG_NAPI_CHECK_RET_D(IMG_IS_OK( | 90 | + if (napi_create_reference(env, thisVar, NUM1, &sConstructor_) != napi_ok) { |
| 274 | - napi_create_reference(env, constructor, 1, &sConstructor_)), | 91 | + IMAGE_ERR("Create reference failed"); |
| 275 | - nullptr, | 92 | + return exports; |
| 276 | - IMAGE_ERR("create reference fail") | 93 | + } |
| 277 | - ); | ||
| 278 | 94 | ||
| 279 | - IMG_NAPI_CHECK_RET_D(IMG_IS_OK( | 95 | + if (napi_set_named_property(env, exports, name, thisVar) != napi_ok) { |
| 280 | - napi_set_named_property(env, exports, CLASS_NAME.c_str(), constructor)), | 96 | + IMAGE_ERR("Define class failed"); |
| 281 | - nullptr, | 97 | + return exports; |
| 282 | - IMAGE_ERR("set named property fail") | 98 | + } |
| 283 | - ); | ||
| 284 | 99 | ||
| 285 | IMAGE_DEBUG("Init success"); | 100 | IMAGE_DEBUG("Init success"); |
| 286 | - | ||
| 287 | - IMAGE_FUNCTION_OUT(); | ||
| 288 | return exports; | 101 | return exports; |
| 289 | } | 102 | } |
| 290 | 103 | ||
| 291 | -std::shared_ptr<ImageNapi> ImageNapi::GetImageSource(napi_env env, napi_value image) | ||
| 292 | -{ | ||
| 293 | - std::unique_ptr<ImageNapi> imageNapi = std::make_unique<ImageNapi>(); | ||
| 294 | 104 | ||
| 295 | - napi_status status = napi_unwrap(env, image, reinterpret_cast<void**>(&imageNapi)); | 105 | +std::shared_ptr<NativeImage> ImageNapi::GetNativeImage(napi_env env, napi_value image) |
| 296 | - if (!IMG_IS_OK(status)) { | 106 | +{ |
| 107 | + ImageNapi* napi = nullptr; | ||
| 108 | + | ||
| 109 | + napi_status status = napi_unwrap(env, image, reinterpret_cast<void**>(&napi)); | ||
| 110 | + if (!IMG_IS_OK(status) || napi == nullptr) { | ||
| 297 | IMAGE_ERR("GetImage napi unwrap failed"); | 111 | IMAGE_ERR("GetImage napi unwrap failed"); |
| 298 | return nullptr; | 112 | return nullptr; |
| 299 | } | 113 | } |
| 114 | + IMAGE_INFO("get nativeImage"); | ||
| 300 | 115 | ||
| 301 | - if (imageNapi == nullptr) { | 116 | + return napi->native_; |
| 302 | - IMAGE_ERR("GetImage imageNapi is nullptr"); | ||
| 303 | - return nullptr; | ||
| 304 | - } | ||
| 305 | - IMAGE_ERR("get nativeImage"); | ||
| 306 | - | ||
| 307 | - return imageNapi; | ||
| 308 | } | 117 | } |
| 309 | 118 | ||
| 310 | napi_value ImageNapi::Constructor(napi_env env, napi_callback_info info) | 119 | napi_value ImageNapi::Constructor(napi_env env, napi_callback_info info) |
| 311 | { | 120 | { |
| 312 | - napi_value undefineVar = nullptr; | ||
| 313 | - napi_get_undefined(env, &undefineVar); | ||
| 314 | - | ||
| 315 | napi_status status; | 121 | napi_status status; |
| 316 | napi_value thisVar = nullptr; | 122 | napi_value thisVar = nullptr; |
| 123 | + napi_value undefineVar; | ||
| 124 | + size_t argc = NUM1; | ||
| 125 | + napi_value argv[NUM1]; | ||
| 317 | 126 | ||
| 318 | IMAGE_FUNCTION_IN(); | 127 | IMAGE_FUNCTION_IN(); |
| 319 | - status = napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); | 128 | + napi_get_undefined(env, &undefineVar); |
| 320 | - if (status == napi_ok && thisVar != nullptr) { | 129 | + status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); |
| 321 | - std::unique_ptr<ImageNapi> reference = std::make_unique<ImageNapi>(); | 130 | + if (status != napi_ok || thisVar == nullptr || argc != NUM1) { |
| 322 | - if (reference != nullptr) { | 131 | + IMAGE_ERR("Constructor Failed to napi_get_cb_info"); |
| 323 | - reference->env_ = env; | 132 | + return undefineVar; |
| 324 | - reference->sSurfaceBuffer_ = staticInstance_; | 133 | + } |
| 325 | - reference->imageReceiver_ = staticImageReceiverInstance_; | 134 | + std::string id; |
| 326 | - staticImageReceiverInstance_ = nullptr; | 135 | + if (!ImageNapiUtils::GetUtf8String(env, argv[NUM0], id) || (id.size() == NUM0)) { |
| 327 | - status = napi_wrap(env, thisVar, reinterpret_cast<void *>(reference.get()), | 136 | + IMAGE_ERR("Failed to parse native image id"); |
| 328 | - ImageNapi::Destructor, nullptr, nullptr); | 137 | + return undefineVar; |
| 329 | - if (status == napi_ok) { | 138 | + } |
| 330 | - IMAGE_FUNCTION_OUT(); | 139 | + std::unique_ptr<ImageNapi> napi = std::make_unique<ImageNapi>(); |
| 331 | - reference.release(); | 140 | + napi->native_ = sNativeImageHolder_.get(id); |
| 332 | - return thisVar; | 141 | + napi->isTestImage_ = false; |
| 333 | - } else { | 142 | + if (napi->native_ == nullptr) { |
| 334 | - IMAGE_ERR("Failure wrapping js to native napi"); | 143 | + if (MY_NAME.compare(id.c_str()) == 0) { |
| 335 | - } | 144 | + napi->isTestImage_ = true; |
| 145 | + } else { | ||
| 146 | + IMAGE_ERR("Failed to get native image"); | ||
| 147 | + return undefineVar; | ||
| 336 | } | 148 | } |
| 337 | } | 149 | } |
| 150 | + status = napi_wrap(env, thisVar, | ||
| 151 | + reinterpret_cast<void *>(napi.get()), ImageNapi::Destructor, nullptr, nullptr); | ||
| 152 | + if (status != napi_ok) { | ||
| 153 | + IMAGE_ERR("Failure wrapping js to native napi"); | ||
| 154 | + return undefineVar; | ||
| 155 | + } | ||
| 338 | 156 | ||
| 339 | - return undefineVar; | 157 | + napi.release(); |
| 158 | + IMAGE_FUNCTION_OUT(); | ||
| 159 | + return thisVar; | ||
| 340 | } | 160 | } |
| 341 | 161 | ||
| 342 | void ImageNapi::Destructor(napi_env env, void *nativeObject, void *finalize) | 162 | void ImageNapi::Destructor(napi_env env, void *nativeObject, void *finalize) |
| 343 | { | 163 | { |
| 164 | + if (nativeObject != nullptr) { | ||
| 165 | + delete reinterpret_cast<ImageNapi *>(nativeObject); | ||
| 166 | + } | ||
| 344 | } | 167 | } |
| 345 | 168 | ||
| 346 | -napi_value ImageNapi::Create(napi_env env, sptr<SurfaceBuffer> surfaceBuffer, | 169 | +napi_value ImageNapi::Create(napi_env env) |
| 347 | - std::shared_ptr<ImageReceiver> imageReceiver) | ||
| 348 | { | 170 | { |
| 349 | - napi_status status; | 171 | + napi_value constructor = nullptr; |
| 350 | - napi_value constructor = nullptr, result = nullptr; | 172 | + napi_value result = nullptr; |
| 173 | + napi_value argv[NUM1]; | ||
| 351 | 174 | ||
| 352 | IMAGE_FUNCTION_IN(); | 175 | IMAGE_FUNCTION_IN(); |
| 353 | - if (surfaceBuffer == nullptr) { | 176 | + if (env == nullptr) { |
| 354 | - IMAGE_ERR("surfaceBuffer is nullptr"); | 177 | + IMAGE_ERR("Input args is invalid"); |
| 355 | - return result; | 178 | + return nullptr; |
| 356 | } | 179 | } |
| 357 | - | 180 | + if (napi_get_reference_value(env, sConstructor_, &constructor) == napi_ok && constructor != nullptr) { |
| 358 | - napi_get_undefined(env, &result); | 181 | + if (napi_create_string_utf8(env, MY_NAME.c_str(), NAPI_AUTO_LENGTH, &(argv[NUM0])) != napi_ok) { |
| 359 | - | 182 | + IMAGE_ERR("Create native image id Failed"); |
| 360 | - status = napi_get_reference_value(env, sConstructor_, &constructor); | 183 | + } |
| 361 | - if (IMG_IS_OK(status)) { | 184 | + if (napi_new_instance(env, constructor, NUM1, argv, &result) != napi_ok) { |
| 362 | - staticInstance_ = surfaceBuffer; | ||
| 363 | - staticImageReceiverInstance_ = imageReceiver; | ||
| 364 | - status = napi_new_instance(env, constructor, 0, nullptr, &result); | ||
| 365 | - if (status == napi_ok) { | ||
| 366 | - IMAGE_FUNCTION_OUT(); | ||
| 367 | - return result; | ||
| 368 | - } else { | ||
| 369 | IMAGE_ERR("New instance could not be obtained"); | 185 | IMAGE_ERR("New instance could not be obtained"); |
| 370 | } | 186 | } |
| 371 | } | 187 | } |
| 372 | - | 188 | + IMAGE_FUNCTION_OUT(); |
| 373 | - IMAGE_ERR("Failed to get reference of constructor"); | ||
| 374 | return result; | 189 | return result; |
| 375 | } | 190 | } |
| 376 | - | 191 | +napi_value ImageNapi::Create(napi_env env, std::shared_ptr<NativeImage> nativeImage) |
| 377 | -napi_value ImageNapi::Create(napi_env env, std::shared_ptr<ImageReceiver> imageReceiver) | ||
| 378 | { | 192 | { |
| 379 | - g_receiverTest = true; | 193 | + napi_value constructor = nullptr; |
| 380 | - napi_status status; | 194 | + napi_value result = nullptr; |
| 381 | - napi_value constructor = nullptr, result = nullptr; | 195 | + napi_value argv[NUM1]; |
| 382 | 196 | ||
| 383 | IMAGE_FUNCTION_IN(); | 197 | IMAGE_FUNCTION_IN(); |
| 384 | - | 198 | + if (env == nullptr || nativeImage == nullptr) { |
| 385 | - napi_get_undefined(env, &result); | 199 | + IMAGE_ERR("Input args is invalid %{public}p vs %{public}p", env, nativeImage.get()); |
| 386 | - status = napi_get_reference_value(env, sConstructor_, &constructor); | 200 | + return nullptr; |
| 387 | - if (IMG_IS_OK(status)) { | 201 | + } |
| 388 | - staticInstance_ = nullptr; | 202 | + if (napi_get_reference_value(env, sConstructor_, &constructor) == napi_ok && constructor != nullptr) { |
| 389 | - staticImageReceiverInstance_ = imageReceiver; | 203 | + auto id = sNativeImageHolder_.save(nativeImage); |
| 390 | - status = napi_new_instance(env, constructor, 0, nullptr, &result); | 204 | + if (napi_create_string_utf8(env, id.c_str(), NAPI_AUTO_LENGTH, &(argv[NUM0])) != napi_ok) { |
| 391 | - if (status == napi_ok) { | 205 | + IMAGE_ERR("Create native image id Failed"); |
| 392 | - IMAGE_FUNCTION_OUT(); | 206 | + } |
| 393 | - return result; | 207 | + if (napi_new_instance(env, constructor, NUM1, argv, &result) != napi_ok) { |
| 394 | - } else { | ||
| 395 | IMAGE_ERR("New instance could not be obtained"); | 208 | IMAGE_ERR("New instance could not be obtained"); |
| 396 | } | 209 | } |
| 397 | } | 210 | } |
| 398 | - | 211 | + IMAGE_FUNCTION_OUT(); |
| 399 | - IMAGE_ERR("Failed to get reference of constructor"); | ||
| 400 | return result; | 212 | return result; |
| 401 | } | 213 | } |
| 402 | - | 214 | +static inline bool JsCheckObjectType(napi_env env, napi_value value, napi_valuetype type) |
| 403 | -napi_value ImageNapi::CreateBufferToImage(napi_env env, sptr<SurfaceBuffer> surfaceBuffer, | ||
| 404 | - std::shared_ptr<ImageCreator> imageCreator) | ||
| 405 | { | 215 | { |
| 406 | - napi_status status; | 216 | + return (ImageNapiUtils::getType(env, value) == type); |
| 407 | - napi_value constructor = nullptr, result = nullptr; | ||
| 408 | - | ||
| 409 | - IMAGE_FUNCTION_IN(); | ||
| 410 | - if (surfaceBuffer == nullptr) { | ||
| 411 | - IMAGE_ERR("surfaceBuffer is nullptr"); | ||
| 412 | - return result; | ||
| 413 | - } | ||
| 414 | - | ||
| 415 | - napi_get_undefined(env, &result); | ||
| 416 | - | ||
| 417 | - status = napi_get_reference_value(env, sConstructor_, &constructor); | ||
| 418 | - if (IMG_IS_OK(status)) { | ||
| 419 | - staticInstance_ = surfaceBuffer; | ||
| 420 | - staticImageCreatorInstance_ = imageCreator; | ||
| 421 | - status = napi_new_instance(env, constructor, 0, nullptr, &result); | ||
| 422 | - if (status == napi_ok) { | ||
| 423 | - IMAGE_FUNCTION_OUT(); | ||
| 424 | - return result; | ||
| 425 | - } else { | ||
| 426 | - IMAGE_ERR("New instance could not be obtained"); | ||
| 427 | - } | ||
| 428 | - } | ||
| 429 | - | ||
| 430 | - IMAGE_ERR("Failed to get reference of constructor"); | ||
| 431 | - return result; | ||
| 432 | } | 217 | } |
| 433 | 218 | ||
| 434 | -unique_ptr<ImageAsyncContext> ImageNapi::UnwarpContext(napi_env env, napi_callback_info info) | 219 | +static inline bool JsGetCallbackFunc(napi_env env, napi_value value, napi_ref *result) |
| 435 | { | 220 | { |
| 436 | - napi_status status; | 221 | + if (JsCheckObjectType(env, value, napi_function)) { |
| 437 | - napi_value thisVar = nullptr; | 222 | + napi_create_reference(env, value, NUM1, result); |
| 438 | - size_t argc = ARGS0; | 223 | + return true; |
| 224 | + } | ||
| 225 | + return false; | ||
| 226 | +} | ||
| 439 | 227 | ||
| 440 | - IMAGE_FUNCTION_IN(); | 228 | +static inline bool JsGetInt32Args(napi_env env, napi_value value, int *result) |
| 441 | - | 229 | +{ |
| 442 | - status = napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr); | 230 | + if (JsCheckObjectType(env, value, napi_number)) { |
| 231 | + napi_get_value_int32(env, value, result); | ||
| 232 | + return true; | ||
| 233 | + } | ||
| 234 | + return false; | ||
| 235 | +} | ||
| 236 | +using AsyncExecCallback = void (*)(napi_env env, ImageAsyncContext* ctx); | ||
| 237 | +using AsyncCompleteCallback = void (*)(napi_env env, napi_status status, ImageAsyncContext* ctx); | ||
| 238 | +static bool JsCreateWork(napi_env env, const char* name, AsyncExecCallback exec, | ||
| 239 | + AsyncCompleteCallback complete, ImageAsyncContext* ctx) | ||
| 240 | +{ | ||
| 241 | + napi_value resource = nullptr; | ||
| 242 | + napi_create_string_utf8(env, name, NAPI_AUTO_LENGTH, &resource); | ||
| 243 | + napi_status status = napi_create_async_work( | ||
| 244 | + env, nullptr, resource, reinterpret_cast<napi_async_execute_callback>(exec), | ||
| 245 | + reinterpret_cast<napi_async_complete_callback>(complete), static_cast<void *>(ctx), &(ctx->work)); | ||
| 443 | if (status != napi_ok) { | 246 | if (status != napi_ok) { |
| 444 | - IMAGE_ERR("fail to napi_get_cb_info %{public}d", status); | 247 | + IMAGE_ERR("fail to create async work %{public}d", status); |
| 248 | + return false; | ||
| 249 | + } | ||
| 250 | + | ||
| 251 | + if (napi_queue_async_work(env, ctx->work) != napi_ok) { | ||
| 252 | + IMAGE_ERR("fail to queue async work"); | ||
| 253 | + return false; | ||
| 254 | + } | ||
| 255 | + return true; | ||
| 256 | +} | ||
| 257 | + | ||
| 258 | +NativeImage* ImageNapi::GetNative() | ||
| 259 | +{ | ||
| 260 | + if (native_ != nullptr) { | ||
| 261 | + return native_.get(); | ||
| 262 | + } | ||
| 263 | + return nullptr; | ||
| 264 | +} | ||
| 265 | + | ||
| 266 | +static std::unique_ptr<ImageAsyncContext> UnwrapContext(napi_env env, napi_callback_info info, | ||
| 267 | + size_t* argc = nullptr, napi_value* argv = nullptr) | ||
| 268 | +{ | ||
| 269 | + napi_value thisVar = nullptr; | ||
| 270 | + size_t tmp = NUM0; | ||
| 271 | + | ||
| 272 | + IMAGE_FUNCTION_IN(); | ||
| 273 | + | ||
| 274 | + if (napi_get_cb_info(env, info, (argc == nullptr)?&tmp:argc, argv, &thisVar, nullptr) != napi_ok) { | ||
| 275 | + IMAGE_ERR("Fail to napi_get_cb_info"); | ||
| 445 | return nullptr; | 276 | return nullptr; |
| 446 | } | 277 | } |
| 447 | 278 | ||
| 448 | - unique_ptr<ImageAsyncContext> context = make_unique<ImageAsyncContext>(); | 279 | + std::unique_ptr<ImageAsyncContext> ctx = std::make_unique<ImageAsyncContext>(); |
| 449 | - status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&context->constructor_)); | 280 | + if (napi_unwrap(env, thisVar, reinterpret_cast<void**>(&ctx->napi)) != napi_ok || ctx->napi == nullptr) { |
| 450 | - if (status != napi_ok || context->constructor_ == nullptr) { | 281 | + IMAGE_ERR("fail to unwrap constructor_"); |
| 451 | - IMAGE_ERR("fail to unwrap constructor_ %{public}d", status); | ||
| 452 | return nullptr; | 282 | return nullptr; |
| 453 | } | 283 | } |
| 454 | - return context; | 284 | + ctx->image = ctx->napi->GetNative(); |
| 285 | + napi_create_reference(env, thisVar, NUM1, &(ctx->thisRef)); | ||
| 286 | + return ctx; | ||
| 287 | +} | ||
| 288 | + | ||
| 289 | +static inline void ProcessPromise(napi_env env, napi_deferred deferred, napi_value* result, bool resolved) | ||
| 290 | +{ | ||
| 291 | + if (resolved) { | ||
| 292 | + napi_resolve_deferred(env, deferred, result[NUM1]); | ||
| 293 | + } else { | ||
| 294 | + napi_reject_deferred(env, deferred, result[NUM0]); | ||
| 295 | + } | ||
| 296 | +} | ||
| 297 | +static inline void ProcessCallback(napi_env env, napi_ref ref, napi_value* result) | ||
| 298 | +{ | ||
| 299 | + napi_value retVal; | ||
| 300 | + napi_value callback; | ||
| 301 | + napi_get_reference_value(env, ref, &callback); | ||
| 302 | + napi_call_function(env, nullptr, callback, NUM2, result, &retVal); | ||
| 303 | + napi_delete_reference(env, ref); | ||
| 304 | +} | ||
| 305 | +static void CommonCallbackRoutine(napi_env env, ImageAsyncContext* &context, const napi_value &valueParam) | ||
| 306 | +{ | ||
| 307 | + IMAGE_FUNCTION_IN(); | ||
| 308 | + napi_value result[2] = {0}; | ||
| 309 | + | ||
| 310 | + if (context == nullptr) { | ||
| 311 | + IMAGE_ERR("context is nullptr"); | ||
| 312 | + return; | ||
| 313 | + } | ||
| 314 | + | ||
| 315 | + if (context->status == SUCCESS) { | ||
| 316 | + napi_create_uint32(env, context->status, &result[0]); | ||
| 317 | + result[1] = valueParam; | ||
| 318 | + } else { | ||
| 319 | + ImageNapiUtils::CreateErrorObj(env, result[0], context->status, | ||
| 320 | + "There is generic napi failure!"); | ||
| 321 | + napi_get_undefined(env, &result[1]); | ||
| 322 | + } | ||
| 323 | + | ||
| 324 | + if (context->deferred) { | ||
| 325 | + ProcessPromise(env, context->deferred, result, context->status == SUCCESS); | ||
| 326 | + } else { | ||
| 327 | + ProcessCallback(env, context->callbackRef, result); | ||
| 328 | + } | ||
| 329 | + | ||
| 330 | + napi_delete_async_work(env, context->work); | ||
| 331 | + | ||
| 332 | + delete context; | ||
| 333 | + context = nullptr; | ||
| 334 | + IMAGE_FUNCTION_OUT(); | ||
| 455 | } | 335 | } |
| 456 | 336 | ||
| 457 | static void BuildIntProperty(napi_env env, const std::string &name, | 337 | static void BuildIntProperty(napi_env env, const std::string &name, |
| @@ -490,96 +370,79 @@ static napi_value BuildJsRegion(napi_env env, int32_t width, | |||
| 490 | napi_value ImageNapi::JSGetClipRect(napi_env env, napi_callback_info info) | 370 | napi_value ImageNapi::JSGetClipRect(napi_env env, napi_callback_info info) |
| 491 | { | 371 | { |
| 492 | napi_value result = nullptr; | 372 | napi_value result = nullptr; |
| 493 | - unique_ptr<ImageAsyncContext> context; | ||
| 494 | 373 | ||
| 495 | IMAGE_FUNCTION_IN(); | 374 | IMAGE_FUNCTION_IN(); |
| 496 | napi_get_undefined(env, &result); | 375 | napi_get_undefined(env, &result); |
| 497 | - context = UnwarpContext(env, info); | 376 | + std::unique_ptr<ImageAsyncContext> context = UnwrapContext(env, info); |
| 498 | - if (context == nullptr) { | 377 | + if (context != nullptr && context->napi != nullptr && context->napi->isTestImage_) { |
| 499 | - return result; | ||
| 500 | - } | ||
| 501 | - | ||
| 502 | - if (context->constructor_ == nullptr) { | ||
| 503 | - IMAGE_ERR("Image context is nullptr"); | ||
| 504 | - return result; | ||
| 505 | - } | ||
| 506 | - auto surfaceBuffer = context->constructor_->sSurfaceBuffer_; | ||
| 507 | - | ||
| 508 | - if (surfaceBuffer == nullptr && g_receiverTest == false) { | ||
| 509 | - IMAGE_ERR("Image surface buffer is nullptr"); | ||
| 510 | - return result; | ||
| 511 | - } | ||
| 512 | - | ||
| 513 | - if (surfaceBuffer != nullptr && g_receiverTest == false) { | ||
| 514 | - return BuildJsRegion(env, surfaceBuffer->GetWidth(), surfaceBuffer->GetHeight(), NUM0, NUM0); | ||
| 515 | - } else { | ||
| 516 | const int32_t WIDTH = 8192; | 378 | const int32_t WIDTH = 8192; |
| 517 | const int32_t HEIGHT = 8; | 379 | const int32_t HEIGHT = 8; |
| 518 | return BuildJsRegion(env, WIDTH, HEIGHT, NUM0, NUM0); | 380 | return BuildJsRegion(env, WIDTH, HEIGHT, NUM0, NUM0); |
| 519 | } | 381 | } |
| 382 | + if (context == nullptr || context->image == nullptr) { | ||
| 383 | + IMAGE_ERR("Image surface buffer is nullptr"); | ||
| 384 | + return result; | ||
| 385 | + } | ||
| 386 | + | ||
| 387 | + int32_t width = NUM0; | ||
| 388 | + int32_t height = NUM0; | ||
| 389 | + if (context->image->GetSize(width, height) != SUCCESS) { | ||
| 390 | + IMAGE_ERR("Image native get size failed"); | ||
| 391 | + return result; | ||
| 392 | + } | ||
| 393 | + return BuildJsRegion(env, width, height, NUM0, NUM0); | ||
| 520 | } | 394 | } |
| 521 | 395 | ||
| 522 | napi_value ImageNapi::JsGetSize(napi_env env, napi_callback_info info) | 396 | napi_value ImageNapi::JsGetSize(napi_env env, napi_callback_info info) |
| 523 | { | 397 | { |
| 524 | napi_value result = nullptr; | 398 | napi_value result = nullptr; |
| 525 | - unique_ptr<ImageAsyncContext> context; | ||
| 526 | 399 | ||
| 527 | IMAGE_FUNCTION_IN(); | 400 | IMAGE_FUNCTION_IN(); |
| 528 | napi_get_undefined(env, &result); | 401 | napi_get_undefined(env, &result); |
| 529 | - context = UnwarpContext(env, info); | 402 | + std::unique_ptr<ImageAsyncContext> context = UnwrapContext(env, info); |
| 530 | - if (context == nullptr) { | 403 | + if (context != nullptr && context->napi != nullptr && context->napi->isTestImage_) { |
| 531 | - return result; | 404 | + const int32_t WIDTH = 8192; |
| 405 | + const int32_t HEIGHT = 8; | ||
| 406 | + return BuildJsSize(env, WIDTH, HEIGHT); | ||
| 532 | } | 407 | } |
| 533 | - | 408 | + if (context == nullptr || context->image == nullptr) { |
| 534 | - if (context->constructor_ == nullptr) { | ||
| 535 | - IMAGE_ERR("Image context is nullptr"); | ||
| 536 | - return result; | ||
| 537 | - } | ||
| 538 | - auto surfaceBuffer = context->constructor_->sSurfaceBuffer_; | ||
| 539 | - | ||
| 540 | - if (surfaceBuffer == nullptr && g_receiverTest == false) { | ||
| 541 | IMAGE_ERR("Image surface buffer is nullptr"); | 409 | IMAGE_ERR("Image surface buffer is nullptr"); |
| 542 | return result; | 410 | return result; |
| 543 | } | 411 | } |
| 544 | 412 | ||
| 545 | - if (surfaceBuffer == nullptr && g_receiverTest == true) { | 413 | + int32_t width = NUM0; |
| 546 | - const int32_t WIDTH = 8192; | 414 | + int32_t height = NUM0; |
| 547 | - const int32_t HEIGHT = 8; | 415 | + if (context->image->GetSize(width, height) != SUCCESS) { |
| 548 | - return BuildJsSize(env, WIDTH, HEIGHT); | 416 | + IMAGE_ERR("Image native get size failed"); |
| 549 | - } else { | 417 | + return result; |
| 550 | - return BuildJsSize(env, surfaceBuffer->GetWidth(), surfaceBuffer->GetHeight()); | ||
| 551 | } | 418 | } |
| 419 | + return BuildJsSize(env, width, height); | ||
| 552 | } | 420 | } |
| 553 | 421 | ||
| 554 | napi_value ImageNapi::JsGetFormat(napi_env env, napi_callback_info info) | 422 | napi_value ImageNapi::JsGetFormat(napi_env env, napi_callback_info info) |
| 555 | { | 423 | { |
| 556 | napi_value result = nullptr; | 424 | napi_value result = nullptr; |
| 557 | - unique_ptr<ImageAsyncContext> context; | ||
| 558 | 425 | ||
| 559 | IMAGE_FUNCTION_IN(); | 426 | IMAGE_FUNCTION_IN(); |
| 560 | napi_get_undefined(env, &result); | 427 | napi_get_undefined(env, &result); |
| 561 | - context = UnwarpContext(env, info); | 428 | + std::unique_ptr<ImageAsyncContext> context = UnwrapContext(env, info); |
| 562 | - if (context == nullptr) { | 429 | + if (context != nullptr && context->napi != nullptr && context->napi->isTestImage_) { |
| 430 | + const int32_t FORMAT = 12; | ||
| 431 | + napi_create_int32(env, FORMAT, &result); | ||
| 563 | return result; | 432 | return result; |
| 564 | } | 433 | } |
| 565 | - | 434 | + if (context == nullptr || context->image == nullptr) { |
| 566 | - if (context->constructor_ == nullptr) { | ||
| 567 | - IMAGE_ERR("Image context is nullptr"); | ||
| 568 | - return result; | ||
| 569 | - } | ||
| 570 | - | ||
| 571 | - auto surfaceBuffer = context->constructor_->sSurfaceBuffer_; | ||
| 572 | - if (surfaceBuffer == nullptr && g_receiverTest == false) { | ||
| 573 | IMAGE_ERR("Image surface buffer is nullptr"); | 435 | IMAGE_ERR("Image surface buffer is nullptr"); |
| 574 | return result; | 436 | return result; |
| 575 | } | 437 | } |
| 576 | 438 | ||
| 577 | - if (surfaceBuffer == nullptr && g_receiverTest == true) { | 439 | + int32_t format = NUM0; |
| 578 | - const int32_t FORMAT = 12; | 440 | + if (context->image->GetFormat(format) != SUCCESS) { |
| 579 | - napi_create_int32(env, FORMAT, &result); | 441 | + IMAGE_ERR("Image native get format failed"); |
| 580 | - } else { | 442 | + return result; |
| 581 | - napi_create_int32(env, surfaceBuffer->GetFormat(), &result); | ||
| 582 | } | 443 | } |
| 444 | + | ||
| 445 | + napi_create_int32(env, format, &result); | ||
| 583 | return result; | 446 | return result; |
| 584 | } | 447 | } |
| 585 | 448 | ||
| @@ -594,9 +457,21 @@ static void JSReleaseCallBack(napi_env env, napi_status status, | |||
| 594 | IMAGE_ERR("context is nullptr"); | 457 | IMAGE_ERR("context is nullptr"); |
| 595 | return; | 458 | return; |
| 596 | } | 459 | } |
| 597 | - context->constructor_->NativeRelease(); | ||
| 598 | - context->status = SUCCESS; | ||
| 599 | 460 | ||
| 461 | + if (context->thisRef != nullptr) { | ||
| 462 | + napi_value thisVar; | ||
| 463 | + napi_get_reference_value(env, context->thisRef, &thisVar); | ||
| 464 | + napi_delete_reference(env, context->thisRef); | ||
| 465 | + if (thisVar != nullptr) { | ||
| 466 | + ImageNapi *tmp = nullptr; | ||
| 467 | + auto status = napi_remove_wrap(env, thisVar, reinterpret_cast<void**>(&tmp)); | ||
| 468 | + if (status != napi_ok) { | ||
| 469 | + IMAGE_ERR("NAPI remove wrap failed status %{public}d", status); | ||
| 470 | + } | ||
| 471 | + } | ||
| 472 | + } | ||
| 473 | + | ||
| 474 | + context->status = SUCCESS; | ||
| 600 | IMAGE_FUNCTION_OUT(); | 475 | IMAGE_FUNCTION_OUT(); |
| 601 | CommonCallbackRoutine(env, context, result); | 476 | CommonCallbackRoutine(env, context, result); |
| 602 | } | 477 | } |
| @@ -604,61 +479,29 @@ static void JSReleaseCallBack(napi_env env, napi_status status, | |||
| 604 | napi_value ImageNapi::JsRelease(napi_env env, napi_callback_info info) | 479 | napi_value ImageNapi::JsRelease(napi_env env, napi_callback_info info) |
| 605 | { | 480 | { |
| 606 | IMAGE_FUNCTION_IN(); | 481 | IMAGE_FUNCTION_IN(); |
| 607 | - napi_status status; | 482 | + napi_value result = nullptr; |
| 608 | - napi_value result = nullptr, thisVar = nullptr; | 483 | + size_t argc = NUM1; |
| 609 | - size_t argc = ARGS1; | 484 | + napi_value argv[NUM1] = {0}; |
| 610 | - napi_value argv[ARGS1] = {0}; | ||
| 611 | 485 | ||
| 612 | napi_get_undefined(env, &result); | 486 | napi_get_undefined(env, &result); |
| 613 | - | 487 | + auto context = UnwrapContext(env, info, &argc, argv); |
| 614 | - status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); | ||
| 615 | - if (status != napi_ok) { | ||
| 616 | - IMAGE_ERR("fail to napi_get_cb_info %{public}d", status); | ||
| 617 | - return result; | ||
| 618 | - } | ||
| 619 | - | ||
| 620 | - unique_ptr<ImageAsyncContext> context = UnwarpContext(env, info); | ||
| 621 | if (context == nullptr) { | 488 | if (context == nullptr) { |
| 622 | - IMAGE_ERR("fail to unwrap constructor_ %{public}d", status); | 489 | + IMAGE_ERR("fail to unwrap constructor_"); |
| 623 | return result; | 490 | return result; |
| 624 | } | 491 | } |
| 625 | - | 492 | + if (argc == NUM1) { |
| 626 | - if (argc == ARGS1) { | 493 | + if (!JsGetCallbackFunc(env, argv[NUM0], &(context->callbackRef))) { |
| 627 | - auto argType = ImageNapiUtils::getType(env, argv[PARAM0]); | 494 | + IMAGE_ERR("Unsupport arg 0 type"); |
| 628 | - if (argType == napi_function) { | ||
| 629 | - int32_t refCount = 1; | ||
| 630 | - napi_create_reference(env, argv[PARAM0], refCount, &context->callbackRef); | ||
| 631 | - } else { | ||
| 632 | - IMAGE_ERR("Unsupport arg 0 type: %{public}d", argType); | ||
| 633 | return result; | 495 | return result; |
| 634 | } | 496 | } |
| 635 | - } | ||
| 636 | - | ||
| 637 | - if (context->callbackRef == nullptr) { | ||
| 638 | - napi_create_promise(env, &(context->deferred), &result); | ||
| 639 | } else { | 497 | } else { |
| 640 | - napi_get_undefined(env, &result); | 498 | + napi_create_promise(env, &(context->deferred), &result); |
| 641 | } | 499 | } |
| 642 | 500 | ||
| 643 | - napi_value resource = nullptr; | 501 | + if (JsCreateWork(env, "JsRelease", [](napi_env env, ImageAsyncContext* data) {}, |
| 644 | - napi_create_string_utf8(env, "JsRelease", NAPI_AUTO_LENGTH, &resource); | 502 | + JSReleaseCallBack, context.get())) { |
| 645 | - status = napi_create_async_work( | 503 | + context.release(); |
| 646 | - env, nullptr, resource, [](napi_env env, void* data) {}, | ||
| 647 | - reinterpret_cast<napi_async_complete_callback>(JSReleaseCallBack), | ||
| 648 | - static_cast<void *>(context.get()), &(context->work)); | ||
| 649 | - if (status != napi_ok) { | ||
| 650 | - IMAGE_ERR("fail to create async work %{public}d", status); | ||
| 651 | - return result; | ||
| 652 | } | 504 | } |
| 653 | - | ||
| 654 | - status = napi_queue_async_work(env, context->work); | ||
| 655 | - if (status != napi_ok) { | ||
| 656 | - IMAGE_ERR("fail to queue async work %{public}d", status); | ||
| 657 | - return result; | ||
| 658 | - } | ||
| 659 | - | ||
| 660 | - context.release(); | ||
| 661 | - | ||
| 662 | IMAGE_FUNCTION_OUT(); | 505 | IMAGE_FUNCTION_OUT(); |
| 663 | return result; | 506 | return result; |
| 664 | } | 507 | } |
| @@ -676,24 +519,44 @@ static bool CreateArrayBuffer(napi_env env, uint8_t* src, size_t srcLen, napi_va | |||
| 676 | return true; | 519 | return true; |
| 677 | } | 520 | } |
| 678 | 521 | ||
| 679 | -static bool IsYUVType(const int32_t& type) | 522 | +static inline bool IsEqual(const int32_t& check, ImageFormat format) |
| 680 | { | 523 | { |
| 681 | - if (type == static_cast<int32_t>(ComponentType::YUV_Y) || | 524 | + return (check == int32_t(format)); |
| 682 | - type == static_cast<int32_t>(ComponentType::YUV_U) || | ||
| 683 | - type == static_cast<int32_t>(ComponentType::YUV_V)) { | ||
| 684 | - return true; | ||
| 685 | - } | ||
| 686 | - return false; | ||
| 687 | } | 525 | } |
| 688 | -static inline bool IsYCbCr422SP(int32_t format) | 526 | +static inline bool IsEqual(const int32_t& check, ComponentType type) |
| 689 | { | 527 | { |
| 690 | - if (format == int32_t(ImageFormat::YCBCR_422_SP)) { | 528 | + return (check == int32_t(type)); |
| 691 | - return true; | 529 | +} |
| 530 | +static inline bool IsYUVComponent(const int32_t& type) | ||
| 531 | +{ | ||
| 532 | + return (IsEqual(type, ComponentType::YUV_Y) || | ||
| 533 | + IsEqual(type, ComponentType::YUV_U) || | ||
| 534 | + IsEqual(type, ComponentType::YUV_V)); | ||
| 535 | +} | ||
| 536 | +static inline bool IsYUV422SPImage(int32_t format) | ||
| 537 | +{ | ||
| 538 | + return (IsEqual(format, ImageFormat::YCBCR_422_SP) || | ||
| 539 | + (format == int32_t(PIXEL_FMT_YCBCR_422_SP))); | ||
| 540 | +} | ||
| 541 | +static inline bool CheckComponentType(const int32_t& type, int32_t format) | ||
| 542 | +{ | ||
| 543 | + return ((IsYUV422SPImage(format) && IsYUVComponent(type)) || | ||
| 544 | + (!IsYUV422SPImage(format) && IsEqual(type, ComponentType::JPEG))); | ||
| 545 | +} | ||
| 546 | + | ||
| 547 | +static bool BuildJsComponentObject(napi_env env, int32_t type, uint8_t* buffer, | ||
| 548 | + NativeComponent* component, napi_value* result) | ||
| 549 | +{ | ||
| 550 | + napi_value array; | ||
| 551 | + if (!CreateArrayBuffer(env, buffer, component->size, &array)) { | ||
| 552 | + return false; | ||
| 692 | } | 553 | } |
| 693 | - if (format == int32_t(PIXEL_FMT_YCBCR_422_SP)) { | 554 | + napi_create_object(env, result); |
| 694 | - return true; | 555 | + napi_set_named_property(env, *result, "byteBuffer", array); |
| 695 | - } | 556 | + BuildIntProperty(env, "componentType", type, *result); |
| 696 | - return false; | 557 | + BuildIntProperty(env, "rowStride", component->rowStride, *result); |
| 558 | + BuildIntProperty(env, "pixelStride", component->pixelStride, *result); | ||
| 559 | + return true; | ||
| 697 | } | 560 | } |
| 698 | static void TestGetComponentCallBack(napi_env env, napi_status status, ImageAsyncContext* context) | 561 | static void TestGetComponentCallBack(napi_env env, napi_status status, ImageAsyncContext* context) |
| 699 | { | 562 | { |
| @@ -715,123 +578,101 @@ static void TestGetComponentCallBack(napi_env env, napi_status status, ImageAsyn | |||
| 715 | context->status = SUCCESS; | 578 | context->status = SUCCESS; |
| 716 | CommonCallbackRoutine(env, context, result); | 579 | CommonCallbackRoutine(env, context, result); |
| 717 | } | 580 | } |
| 718 | -void ImageNapi::JsGetComponentCallBack(napi_env env, napi_status status, ImageAsyncContext* context) | 581 | + |
| 582 | +static void JsGetComponentCallBack(napi_env env, napi_status status, ImageAsyncContext* context) | ||
| 719 | { | 583 | { |
| 720 | IMAGE_FUNCTION_IN(); | 584 | IMAGE_FUNCTION_IN(); |
| 721 | napi_value result; | 585 | napi_value result; |
| 722 | napi_get_undefined(env, &result); | 586 | napi_get_undefined(env, &result); |
| 723 | - if (g_receiverTest) { | 587 | + |
| 588 | + if (context != nullptr && context->napi != nullptr && context->isTestContext) { | ||
| 724 | TestGetComponentCallBack(env, status, context); | 589 | TestGetComponentCallBack(env, status, context); |
| 725 | return; | 590 | return; |
| 726 | } | 591 | } |
| 727 | - if (context == nullptr || context->constructor_ == nullptr || | 592 | + |
| 728 | - context->constructor_->sSurfaceBuffer_ == nullptr) { | 593 | + if (context == nullptr) { |
| 729 | HiLog::Error(LABEL, "Invalid input context"); | 594 | HiLog::Error(LABEL, "Invalid input context"); |
| 730 | return; | 595 | return; |
| 731 | } | 596 | } |
| 732 | - auto surfaceBuffer = context->constructor_->sSurfaceBuffer_; | 597 | + context->status = ERROR; |
| 733 | - uint32_t bufferSize = 0; | 598 | + NativeComponent* component = context->component; |
| 599 | + if (component == nullptr) { | ||
| 600 | + HiLog::Error(LABEL, "Invalid component"); | ||
| 601 | + CommonCallbackRoutine(env, context, result); | ||
| 602 | + return; | ||
| 603 | + } | ||
| 604 | + | ||
| 734 | uint8_t *buffer = nullptr; | 605 | uint8_t *buffer = nullptr; |
| 735 | - uint32_t rowStride = 0; | 606 | + if (component->virAddr != nullptr) { |
| 736 | - uint32_t pixelStride = 0; | 607 | + buffer = component->virAddr; |
| 737 | - if (IsYCbCr422SP(surfaceBuffer->GetFormat()) && IsYUVType(context->componentType)) { | ||
| 738 | - Component* component = context->constructor_->GetComponentData( | ||
| 739 | - ComponentType(context->componentType)); | ||
| 740 | - if (component != nullptr) { | ||
| 741 | - bufferSize = component->raw.size(); | ||
| 742 | - buffer = component->raw.data(); | ||
| 743 | - rowStride = component->rowStride; | ||
| 744 | - pixelStride = component->pixelStride; | ||
| 745 | - } else { | ||
| 746 | - context->status = ERROR; | ||
| 747 | - HiLog::Error(LABEL, "Failed to GetComponentData"); | ||
| 748 | - } | ||
| 749 | } else { | 608 | } else { |
| 750 | - bufferSize = GetSurfaceDataSize(surfaceBuffer); | 609 | + buffer = component->raw.data(); |
| 751 | - buffer = static_cast<uint8_t*>(surfaceBuffer->GetVirAddr()); | ||
| 752 | - rowStride = surfaceBuffer->GetWidth(); | ||
| 753 | - pixelStride = NUM1; | ||
| 754 | } | 610 | } |
| 755 | - if (buffer != nullptr && bufferSize != NUM0) { | 611 | + |
| 756 | - napi_value array; | 612 | + if (buffer == nullptr || component->size == NUM0) { |
| 757 | - if (CreateArrayBuffer(env, buffer, bufferSize, &array)) { | 613 | + HiLog::Error(LABEL, "Invalid buffer"); |
| 758 | - napi_create_object(env, &result); | 614 | + CommonCallbackRoutine(env, context, result); |
| 759 | - napi_set_named_property(env, result, "byteBuffer", array); | 615 | + return; |
| 760 | - BuildIntProperty(env, "componentType", context->componentType, result); | 616 | + } |
| 761 | - BuildIntProperty(env, "rowStride", rowStride, result); | 617 | + |
| 762 | - BuildIntProperty(env, "pixelStride", pixelStride, result); | 618 | + if (BuildJsComponentObject(env, context->componentType, buffer, component, &result)) { |
| 763 | - context->status = SUCCESS; | 619 | + context->status = SUCCESS; |
| 764 | - } else { | ||
| 765 | - HiLog::Error(LABEL, "napi_create_arraybuffer failed!"); | ||
| 766 | - } | ||
| 767 | } else { | 620 | } else { |
| 768 | - HiLog::Error(LABEL, "buffer is nullptr or bufferSize is %{public}" PRIu32, bufferSize); | 621 | + HiLog::Error(LABEL, "napi_create_arraybuffer failed!"); |
| 769 | } | 622 | } |
| 623 | + | ||
| 770 | IMAGE_FUNCTION_OUT(); | 624 | IMAGE_FUNCTION_OUT(); |
| 771 | CommonCallbackRoutine(env, context, result); | 625 | CommonCallbackRoutine(env, context, result); |
| 772 | } | 626 | } |
| 773 | static void JsGetComponentExec(napi_env env, ImageAsyncContext* context) | 627 | static void JsGetComponentExec(napi_env env, ImageAsyncContext* context) |
| 774 | { | 628 | { |
| 775 | - if (context == nullptr || context->constructor_ == nullptr || | 629 | + if (context == nullptr || context->napi == nullptr) { |
| 776 | - context->constructor_->sSurfaceBuffer_ == nullptr) { | ||
| 777 | HiLog::Error(LABEL, "Invalid input context"); | 630 | HiLog::Error(LABEL, "Invalid input context"); |
| 778 | return; | 631 | return; |
| 779 | } | 632 | } |
| 780 | - auto surfaceBuffer = context->constructor_->sSurfaceBuffer_; | ||
| 781 | - HiLog::Info(LABEL, | ||
| 782 | - "JsGetComponentExec surface buffer type %{public}" PRId32, surfaceBuffer->GetFormat()); | ||
| 783 | - context->status = SplitSurfaceToComponent(context->constructor_, surfaceBuffer); | ||
| 784 | -} | ||
| 785 | 633 | ||
| 786 | -static bool CheckComponentType(const int32_t& type, int32_t format) | 634 | + auto native = context->napi->GetNative(); |
| 787 | -{ | 635 | + if (native == nullptr) { |
| 788 | - if (IsYCbCr422SP(format) && IsYUVType(type)) { | 636 | + HiLog::Error(LABEL, "Empty native"); |
| 789 | - return true; | 637 | + return; |
| 790 | } | 638 | } |
| 791 | - if (!IsYCbCr422SP(format) && type == static_cast<int32_t>(ComponentType::JPEG)) { | 639 | + context->component = native->GetComponent(context->componentType); |
| 792 | - return true; | ||
| 793 | - } | ||
| 794 | - return false; | ||
| 795 | } | 640 | } |
| 796 | 641 | ||
| 797 | static bool JsGetComponentArgs(napi_env env, size_t argc, napi_value* argv, ImageAsyncContext* context) | 642 | static bool JsGetComponentArgs(napi_env env, size_t argc, napi_value* argv, ImageAsyncContext* context) |
| 798 | { | 643 | { |
| 799 | - if (argv == nullptr || context == nullptr) { | 644 | + if (argv == nullptr || context == nullptr || argc < NUM1 || context->napi == nullptr) { |
| 800 | IMAGE_ERR("argv is nullptr"); | 645 | IMAGE_ERR("argv is nullptr"); |
| 801 | return false; | 646 | return false; |
| 802 | } | 647 | } |
| 803 | 648 | ||
| 804 | - if (context->constructor_ == nullptr || | 649 | + if (!JsGetInt32Args(env, argv[NUM0], &(context->componentType))) { |
| 805 | - (!g_receiverTest && context->constructor_->sSurfaceBuffer_ == nullptr)) { | 650 | + IMAGE_ERR("Unsupport arg 0 type"); |
| 806 | - IMAGE_ERR("Constructor is nullptr"); | ||
| 807 | return false; | 651 | return false; |
| 808 | } | 652 | } |
| 809 | 653 | ||
| 810 | - if (argc == ARGS1 || argc == ARGS2) { | 654 | + auto native = context->napi->GetNative(); |
| 811 | - auto argType0 = ImageNapiUtils::getType(env, argv[PARAM0]); | 655 | + if (native == nullptr && !context->isTestContext) { |
| 812 | - if (argType0 == napi_number) { | 656 | + IMAGE_ERR("native is nullptr"); |
| 813 | - napi_get_value_int32(env, argv[PARAM0], &(context->componentType)); | 657 | + return false; |
| 814 | - } else { | ||
| 815 | - IMAGE_ERR("Unsupport arg 0 type: %{public}d", argType0); | ||
| 816 | - return false; | ||
| 817 | - } | ||
| 818 | - if (!g_receiverTest) { | ||
| 819 | - auto surfaceBuffer = context->constructor_->sSurfaceBuffer_; | ||
| 820 | - if (!CheckComponentType(context->componentType, surfaceBuffer->GetFormat())) { | ||
| 821 | - IMAGE_ERR("Unsupport component type 0 value: %{public}d", context->componentType); | ||
| 822 | - return false; | ||
| 823 | - } | ||
| 824 | - } | ||
| 825 | } | 658 | } |
| 826 | - if (argc == ARGS2) { | 659 | + |
| 827 | - auto argType1 = ImageNapiUtils::getType(env, argv[PARAM1]); | 660 | + int32_t format = NUM0; |
| 828 | - if (argType1 == napi_function) { | 661 | + if (context->isTestContext) { |
| 829 | - int32_t refCount = 1; | 662 | + const int32_t TEST_FORMAT = 12; |
| 830 | - napi_create_reference(env, argv[PARAM1], refCount, &(context->callbackRef)); | 663 | + format = TEST_FORMAT; |
| 831 | - } else { | 664 | + } else { |
| 832 | - IMAGE_ERR("Unsupport arg 1 type: %{public}d", argType1); | 665 | + native->GetFormat(format); |
| 833 | - return false; | 666 | + } |
| 834 | - } | 667 | + |
| 668 | + if (!CheckComponentType(context->componentType, format)) { | ||
| 669 | + IMAGE_ERR("Unsupport component type 0 value: %{public}d", context->componentType); | ||
| 670 | + return false; | ||
| 671 | + } | ||
| 672 | + | ||
| 673 | + if (argc == NUM2 && !JsGetCallbackFunc(env, argv[NUM1], &(context->callbackRef))) { | ||
| 674 | + IMAGE_ERR("Unsupport arg 1 type"); | ||
| 675 | + return false; | ||
| 835 | } | 676 | } |
| 836 | return true; | 677 | return true; |
| 837 | } | 678 | } |
| @@ -839,26 +680,17 @@ static bool JsGetComponentArgs(napi_env env, size_t argc, napi_value* argv, Imag | |||
| 839 | napi_value ImageNapi::JsGetComponent(napi_env env, napi_callback_info info) | 680 | napi_value ImageNapi::JsGetComponent(napi_env env, napi_callback_info info) |
| 840 | { | 681 | { |
| 841 | IMAGE_FUNCTION_IN(); | 682 | IMAGE_FUNCTION_IN(); |
| 842 | - napi_status status; | 683 | + napi_value result = nullptr; |
| 843 | - napi_value result = nullptr, thisVar = nullptr; | 684 | + size_t argc = NUM2; |
| 844 | - size_t argc = ARGS2; | 685 | + napi_value argv[NUM2] = {0}; |
| 845 | - napi_value argv[ARGS2] = {0}; | ||
| 846 | 686 | ||
| 847 | napi_get_undefined(env, &result); | 687 | napi_get_undefined(env, &result); |
| 848 | - | 688 | + auto context = UnwrapContext(env, info, &argc, argv); |
| 849 | - status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); | ||
| 850 | - if (status != napi_ok) { | ||
| 851 | - IMAGE_ERR("fail to napi_get_cb_info %{public}d", status); | ||
| 852 | - return result; | ||
| 853 | - } | ||
| 854 | - | ||
| 855 | - unique_ptr<ImageAsyncContext> context = UnwarpContext(env, info); | ||
| 856 | if (context == nullptr) { | 689 | if (context == nullptr) { |
| 857 | - std::string errMsg = "fail to unwrap constructor_ "; | ||
| 858 | return ImageNapiUtils::ThrowExceptionError(env, static_cast<int32_t>(napi_invalid_arg), | 690 | return ImageNapiUtils::ThrowExceptionError(env, static_cast<int32_t>(napi_invalid_arg), |
| 859 | - errMsg.append(std::to_string(status))); | 691 | + "fail to unwrap constructor_ "); |
| 860 | } | 692 | } |
| 861 | - | 693 | + context->isTestContext = context->napi->isTestImage_; |
| 862 | if (!JsGetComponentArgs(env, argc, argv, context.get())) { | 694 | if (!JsGetComponentArgs(env, argc, argv, context.get())) { |
| 863 | return ImageNapiUtils::ThrowExceptionError(env, static_cast<int32_t>(napi_invalid_arg), | 695 | return ImageNapiUtils::ThrowExceptionError(env, static_cast<int32_t>(napi_invalid_arg), |
| 864 | "Unsupport arg type!"); | 696 | "Unsupport arg type!"); |
| @@ -866,93 +698,14 @@ napi_value ImageNapi::JsGetComponent(napi_env env, napi_callback_info info) | |||
| 866 | 698 | ||
| 867 | if (context->callbackRef == nullptr) { | 699 | if (context->callbackRef == nullptr) { |
| 868 | napi_create_promise(env, &(context->deferred), &result); | 700 | napi_create_promise(env, &(context->deferred), &result); |
| 869 | - } else { | ||
| 870 | - napi_get_undefined(env, &result); | ||
| 871 | } | 701 | } |
| 872 | 702 | ||
| 873 | - napi_value resource = nullptr; | 703 | + if (JsCreateWork(env, "JsGetComponent", JsGetComponentExec, JsGetComponentCallBack, context.get())) { |
| 874 | - napi_create_string_utf8(env, "JsGetComponent", NAPI_AUTO_LENGTH, &resource); | 704 | + context.release(); |
| 875 | - status = napi_create_async_work( | ||
| 876 | - env, nullptr, resource, | ||
| 877 | - reinterpret_cast<napi_async_execute_callback>(JsGetComponentExec), | ||
| 878 | - reinterpret_cast<napi_async_complete_callback>(JsGetComponentCallBack), | ||
| 879 | - static_cast<void *>(context.get()), &(context->work)); | ||
| 880 | - if (status != napi_ok) { | ||
| 881 | - IMAGE_ERR("fail to create async work %{public}d", status); | ||
| 882 | - return result; | ||
| 883 | } | 705 | } |
| 884 | 706 | ||
| 885 | - status = napi_queue_async_work(env, context->work); | ||
| 886 | - if (status != napi_ok) { | ||
| 887 | - IMAGE_ERR("fail to queue async work %{public}d", status); | ||
| 888 | - return result; | ||
| 889 | - } | ||
| 890 | - context.release(); | ||
| 891 | - | ||
| 892 | IMAGE_FUNCTION_OUT(); | 707 | IMAGE_FUNCTION_OUT(); |
| 893 | return result; | 708 | return result; |
| 894 | } | 709 | } |
| 895 | - | ||
| 896 | -void ImageNapi::release() | ||
| 897 | -{ | ||
| 898 | - if (!isRelease) { | ||
| 899 | - NativeRelease(); | ||
| 900 | - isRelease = true; | ||
| 901 | - } | ||
| 902 | -} | ||
| 903 | -Component* ImageNapi::CreateComponentData(ComponentType type, size_t size, | ||
| 904 | - int32_t rowStride, int32_t pixelStride) | ||
| 905 | -{ | ||
| 906 | - Component* result = nullptr; | ||
| 907 | - if (size == NUM0) { | ||
| 908 | - HiLog::Error(LABEL, "Could't create 0 size component data"); | ||
| 909 | - return result; | ||
| 910 | - } | ||
| 911 | - auto iter = componentData_.find(type); | ||
| 912 | - if (iter != componentData_.end()) { | ||
| 913 | - HiLog::Info(LABEL, "Component %{public}d already exist. No need create", type); | ||
| 914 | - return iter->second.get(); | ||
| 915 | - } | ||
| 916 | - std::unique_ptr<Component> component = std::make_unique<Component>(); | ||
| 917 | - component->pixelStride = pixelStride; | ||
| 918 | - component->rowStride = rowStride; | ||
| 919 | - component->raw.resize(size); | ||
| 920 | - componentData_.insert(std::map<ComponentType, std::unique_ptr<Component>>::value_type(type, | ||
| 921 | - std::move(component))); | ||
| 922 | - result = GetComponentData(type); | ||
| 923 | - return result; | ||
| 924 | -} | ||
| 925 | -Component* ImageNapi::GetComponentData(ComponentType type) | ||
| 926 | -{ | ||
| 927 | - auto iter = componentData_.find(type); | ||
| 928 | - if (iter != componentData_.end()) { | ||
| 929 | - return iter->second.get(); | ||
| 930 | - } | ||
| 931 | - return nullptr; | ||
| 932 | -} | ||
| 933 | -uint32_t ImageNapi::CombineComponentsIntoSurface() | ||
| 934 | -{ | ||
| 935 | - if (!IsYCbCr422SP(sSurfaceBuffer_->GetFormat())) { | ||
| 936 | - HiLog::Info(LABEL, "No need to combine components for NO YUV format now"); | ||
| 937 | - return SUCCESS; | ||
| 938 | - } | ||
| 939 | - Component* y = GetComponentData(ComponentType::YUV_Y); | ||
| 940 | - Component* u = GetComponentData(ComponentType::YUV_U); | ||
| 941 | - Component* v = GetComponentData(ComponentType::YUV_V); | ||
| 942 | - if ((y == nullptr) || (u == nullptr) || (v == nullptr)) { | ||
| 943 | - HiLog::Error(LABEL, "No component need to combine"); | ||
| 944 | - return ERR_IMAGE_DATA_ABNORMAL; | ||
| 945 | - } | ||
| 946 | - uint32_t bufferSize = GetSurfaceDataSize(sSurfaceBuffer_); | ||
| 947 | - uint8_t* buffer = static_cast<uint8_t*>(sSurfaceBuffer_->GetVirAddr()); | ||
| 948 | - struct YUV422SPData data; | ||
| 949 | - data.ySize = y->raw.size(); | ||
| 950 | - data.uvSize = u->raw.size(); | ||
| 951 | - data.y = y->raw; | ||
| 952 | - data.u = u->raw; | ||
| 953 | - data.v = v->raw; | ||
| 954 | - YUV422SPDataCopy(buffer, bufferSize, data, true); | ||
| 955 | - return SUCCESS; | ||
| 956 | -} | ||
| 957 | } // namespace Media | 710 | } // namespace Media |
| 958 | } // namespace OHOS | 711 | } // namespace OHOS |
| @@ -0,0 +1,199 @@ | |||
| 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 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | +namespace OHOS { | ||
| 23 | +namespace Media { | ||
| 24 | +using ImageReceiverNapiEnvFunc = int32_t (*)(napi_env env, struct ImageReceiverArgs* args); | ||
| 25 | +using ImageReceiverNapiCtxFunc = int32_t (*)(ImageReceiverNapi* native, struct ImageReceiverArgs* args); | ||
| 26 | + | ||
| 27 | +extern "C" { | ||
| 28 | + | ||
| 29 | +static ImageReceiver* GetNativeReceiver(ImageReceiverNapi* napi) | ||
| 30 | +{ | ||
| 31 | + if (napi == nullptr) { | ||
| 32 | + return nullptr; | ||
| 33 | + } | ||
| 34 | + return napi->GetNative(); | ||
| 35 | +} | ||
| 36 | + | ||
| 37 | +static ImageReceiver* CheckAndGetReceiver(ImageReceiverNapi* native, struct ImageReceiverArgs* args) | ||
| 38 | +{ | ||
| 39 | + if (args == nullptr) { | ||
| 40 | + return nullptr; | ||
| 41 | + } | ||
| 42 | + return GetNativeReceiver(native); | ||
| 43 | +} | ||
| 44 | + | ||
| 45 | +static int32_t ImageReceiverNapiCreate(napi_env env, struct ImageReceiverArgs* args) | ||
| 46 | +{ | ||
| 47 | + if (args == nullptr) { | ||
| 48 | + return OHOS_IMAGE_RESULT_BAD_PARAMETER; | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + ImageReceiverCreateArgs createArgs; | ||
| 52 | + createArgs.width = args->inNum0; | ||
| 53 | + createArgs.height = args->inNum1; | ||
| 54 | + createArgs.format = args->inNum2; | ||
| 55 | + createArgs.capicity = args->inNum3; | ||
| 56 | + *(args->outValue) = ImageReceiverNapi::CreateImageReceiverJsObject(env, createArgs); | ||
| 57 | + if (*(args->outValue) == nullptr) { | ||
| 58 | + return OHOS_IMAGE_RESULT_BAD_PARAMETER; | ||
| 59 | + } | ||
| 60 | + return OHOS_IMAGE_RESULT_SUCCESS; | ||
| 61 | +} | ||
| 62 | + | ||
| 63 | +static int32_t ImageReceiverNapiGetReceiverId(ImageReceiverNapi* native, struct ImageReceiverArgs* args) | ||
| 64 | +{ | ||
| 65 | + auto receiver = CheckAndGetReceiver(native, args); | ||
| 66 | + if (receiver == nullptr || receiver->iraContext_ == nullptr || args->id == nullptr) { | ||
| 67 | + return OHOS_IMAGE_RESULT_BAD_PARAMETER; | ||
| 68 | + } | ||
| 69 | + auto sId = receiver->iraContext_->GetReceiverKey(); | ||
| 70 | + if (sId.empty() || sId.c_str() == nullptr || args->inLen < sId.size()) { | ||
| 71 | + return OHOS_IMAGE_RESULT_BAD_PARAMETER; | ||
| 72 | + } | ||
| 73 | + memcpy_s(args->id, args->inLen, sId.c_str(), sId.size()); | ||
| 74 | + return OHOS_IMAGE_RESULT_SUCCESS; | ||
| 75 | +} | ||
| 76 | + | ||
| 77 | +static int32_t ImageReceiverNapiReadLatestImage(ImageReceiverNapi* native, struct ImageReceiverArgs* args) | ||
| 78 | +{ | ||
| 79 | + auto receiver = CheckAndGetReceiver(native, args); | ||
| 80 | + if (receiver == nullptr || args->inEnv == nullptr) { | ||
| 81 | + return OHOS_IMAGE_RESULT_BAD_PARAMETER; | ||
| 82 | + } | ||
| 83 | + auto image = receiver->LastNativeImage(); | ||
| 84 | + if (image == nullptr) { | ||
| 85 | + return OHOS_IMAGE_RESULT_BAD_PARAMETER; | ||
| 86 | + } | ||
| 87 | + *(args->outValue) = ImageNapi::Create(args->inEnv, image); | ||
| 88 | + return OHOS_IMAGE_RESULT_SUCCESS; | ||
| 89 | +} | ||
| 90 | + | ||
| 91 | +static int32_t ImageReceiverNapiReadNextImage(ImageReceiverNapi* native, struct ImageReceiverArgs* args) | ||
| 92 | +{ | ||
| 93 | + auto receiver = CheckAndGetReceiver(native, args); | ||
| 94 | + if (receiver == nullptr || args->inEnv == nullptr) { | ||
| 95 | + return OHOS_IMAGE_RESULT_BAD_PARAMETER; | ||
| 96 | + } | ||
| 97 | + auto image = receiver->NextNativeImage(); | ||
| 98 | + if (image == nullptr) { | ||
| 99 | + return OHOS_IMAGE_RESULT_BAD_PARAMETER; | ||
| 100 | + } | ||
| 101 | + *(args->outValue) = ImageNapi::Create(args->inEnv, image); | ||
| 102 | + return OHOS_IMAGE_RESULT_SUCCESS; | ||
| 103 | +} | ||
| 104 | + | ||
| 105 | +static int32_t ImageReceiverNapiOn(ImageReceiverNapi* native, struct ImageReceiverArgs* args) | ||
| 106 | +{ | ||
| 107 | + auto receiver = CheckAndGetReceiver(native, args); | ||
| 108 | + if (receiver == nullptr || args->callback == nullptr) { | ||
| 109 | + return OHOS_IMAGE_RESULT_BAD_PARAMETER; | ||
| 110 | + } | ||
| 111 | + std::shared_ptr<ImageReceiverNapiListener> listener = std::make_shared<ImageReceiverNapiListener>(); | ||
| 112 | + listener->callBack = args->callback; | ||
| 113 | + receiver->RegisterBufferAvaliableListener(listener); | ||
| 114 | + return OHOS_IMAGE_RESULT_SUCCESS; | ||
| 115 | +} | ||
| 116 | + | ||
| 117 | +static int32_t ImageReceiverNapiGetSize(ImageReceiverNapi* native, struct ImageReceiverArgs* args) | ||
| 118 | +{ | ||
| 119 | + auto receiver = CheckAndGetReceiver(native, args); | ||
| 120 | + if (receiver == nullptr || receiver->iraContext_ == nullptr || args->outSize == nullptr) { | ||
| 121 | + return OHOS_IMAGE_RESULT_BAD_PARAMETER; | ||
| 122 | + } | ||
| 123 | + args->outSize->width = receiver->iraContext_->GetWidth(); | ||
| 124 | + args->outSize->height = receiver->iraContext_->GetHeight(); | ||
| 125 | + return OHOS_IMAGE_RESULT_SUCCESS; | ||
| 126 | +} | ||
| 127 | + | ||
| 128 | +static int32_t ImageReceiverNapiGetCapacity(ImageReceiverNapi* native, struct ImageReceiverArgs* args) | ||
| 129 | +{ | ||
| 130 | + auto receiver = CheckAndGetReceiver(native, args); | ||
| 131 | + if (receiver == nullptr || receiver->iraContext_ == nullptr) { | ||
| 132 | + return OHOS_IMAGE_RESULT_BAD_PARAMETER; | ||
| 133 | + } | ||
| 134 | + *(args->outNum0) = receiver->iraContext_->GetCapicity(); | ||
| 135 | + return OHOS_IMAGE_RESULT_SUCCESS; | ||
| 136 | +} | ||
| 137 | + | ||
| 138 | +static int32_t ImageReceiverNapiGetFormat(ImageReceiverNapi* native, struct ImageReceiverArgs* args) | ||
| 139 | +{ | ||
| 140 | + auto receiver = CheckAndGetReceiver(native, args); | ||
| 141 | + if (receiver == nullptr || receiver->iraContext_ == nullptr) { | ||
| 142 | + return OHOS_IMAGE_RESULT_BAD_PARAMETER; | ||
| 143 | + } | ||
| 144 | + *(args->outNum0) = receiver->iraContext_->GetFormat(); | ||
| 145 | + return OHOS_IMAGE_RESULT_SUCCESS; | ||
| 146 | +} | ||
| 147 | +static const std::map<int32_t, ImageReceiverNapiEnvFunc> g_EnvFunctions = { | ||
| 148 | + {ENV_FUNC_IMAGE_RECEIVER_CREATE, ImageReceiverNapiCreate}, | ||
| 149 | +}; | ||
| 150 | +static const std::map<int32_t, ImageReceiverNapiCtxFunc> g_CtxFunctions = { | ||
| 151 | + {CTX_FUNC_IMAGE_RECEIVER_GET_RECEIVER_ID, ImageReceiverNapiGetReceiverId}, | ||
| 152 | + {CTX_FUNC_IMAGE_RECEIVER_READ_LATEST_IMAGE, ImageReceiverNapiReadLatestImage}, | ||
| 153 | + {CTX_FUNC_IMAGE_RECEIVER_READ_NEXT_IMAGE, ImageReceiverNapiReadNextImage}, | ||
| 154 | + {CTX_FUNC_IMAGE_RECEIVER_ON, ImageReceiverNapiOn}, | ||
| 155 | + {CTX_FUNC_IMAGE_RECEIVER_GET_SIZE, ImageReceiverNapiGetSize}, | ||
| 156 | + {CTX_FUNC_IMAGE_RECEIVER_GET_CAPACITY, ImageReceiverNapiGetCapacity}, | ||
| 157 | + {CTX_FUNC_IMAGE_RECEIVER_GET_FORMAT, ImageReceiverNapiGetFormat}, | ||
| 158 | +}; | ||
| 159 | + | ||
| 160 | +MIDK_EXPORT | ||
| 161 | +int32_t ImageReceiverNativeEnvCall(int32_t mode, napi_env env, struct ImageReceiverArgs* args) | ||
| 162 | +{ | ||
| 163 | + auto funcSearch = g_EnvFunctions.find(mode); | ||
| 164 | + if (funcSearch == g_EnvFunctions.end()) { | ||
| 165 | + return OHOS_IMAGE_RESULT_BAD_PARAMETER; | ||
| 166 | + } | ||
| 167 | + return funcSearch->second(env, args); | ||
| 168 | +} | ||
| 169 | + | ||
| 170 | +MIDK_EXPORT | ||
| 171 | +int32_t ImageReceiverNativeCtxCall(int32_t mode, ImageReceiverNapi* native, struct ImageReceiverArgs* args) | ||
| 172 | +{ | ||
| 173 | + auto funcSearch = g_CtxFunctions.find(mode); | ||
| 174 | + if (funcSearch == g_CtxFunctions.end()) { | ||
| 175 | + return OHOS_IMAGE_RESULT_BAD_PARAMETER; | ||
| 176 | + } | ||
| 177 | + return funcSearch->second(native, args); | ||
| 178 | +} | ||
| 179 | + | ||
| 180 | +MIDK_EXPORT | ||
| 181 | +ImageReceiverNapi* ImageReceiver_Unwrap(napi_env env, napi_value value) | ||
| 182 | +{ | ||
| 183 | + napi_valuetype valueType; | ||
| 184 | + napi_typeof(env, value, &valueType); | ||
| 185 | + if (valueType != napi_object) { | ||
| 186 | + return nullptr; | ||
| 187 | + } | ||
| 188 | + std::unique_ptr<ImageReceiverNapi> receiverNapi = nullptr; | ||
| 189 | + napi_status status = napi_unwrap(env, value, reinterpret_cast<void**>(&receiverNapi)); | ||
| 190 | + if ((status == napi_ok) && receiverNapi != nullptr) { | ||
| 191 | + return receiverNapi.release(); | ||
| 192 | + } | ||
| 193 | + return nullptr; | ||
| 194 | +} | ||
| 195 | + | ||
| 196 | +}; | ||
| 197 | + | ||
| 198 | +} // namespace Media | ||
| 199 | +} // namespace OHOS | ||
| @@ -122,6 +122,13 @@ void ImageReceiverNapi::NativeRelease() | |||
| 122 | } | 122 | } |
| 123 | } | 123 | } |
| 124 | 124 | ||
| 125 | +ImageReceiver* ImageReceiverNapi::GetNative() | ||
| 126 | +{ | ||
| 127 | + if (imageReceiver_ != nullptr) { | ||
| 128 | + return imageReceiver_.get(); | ||
| 129 | + } | ||
| 130 | + return nullptr; | ||
| 131 | +} | ||
| 125 | napi_value ImageReceiverNapi::Init(napi_env env, napi_value exports) | 132 | napi_value ImageReceiverNapi::Init(napi_env env, napi_value exports) |
| 126 | { | 133 | { |
| 127 | IMAGE_FUNCTION_IN(); | 134 | IMAGE_FUNCTION_IN(); |
| @@ -177,33 +184,75 @@ napi_value ImageReceiverNapi::Init(napi_env env, napi_value exports) | |||
| 177 | return exports; | 184 | return exports; |
| 178 | } | 185 | } |
| 179 | 186 | ||
| 187 | +struct ImageReceiverInputArgs { | ||
| 188 | + napi_value thisVar; | ||
| 189 | + size_t argc; | ||
| 190 | + napi_value argv[ARGS4]; | ||
| 191 | + int32_t args[ARGS4]; | ||
| 192 | +}; | ||
| 193 | + | ||
| 194 | +static bool parseImageReceiverArgs(napi_env env, napi_callback_info info, | ||
| 195 | + ImageReceiverInputArgs &args, std::string &errMsg) | ||
| 196 | +{ | ||
| 197 | + napi_status status = napi_get_cb_info(env, info, &(args.argc), args.argv, &(args.thisVar), nullptr); | ||
| 198 | + if (status != napi_ok) { | ||
| 199 | + IMAGE_ERR("fail to napi_get_cb_info %{public}d", status); | ||
| 200 | + errMsg = "Fail to napi_get_cb_info"; | ||
| 201 | + return false; | ||
| 202 | + } | ||
| 203 | + | ||
| 204 | + if (args.argc != ARGS4) { | ||
| 205 | + errMsg = "Invailed arg counts "; | ||
| 206 | + errMsg.append(std::to_string(args.argc)); | ||
| 207 | + return false; | ||
| 208 | + } | ||
| 209 | + | ||
| 210 | + for (size_t i = PARAM0; i < args.argc; i++) { | ||
| 211 | + napi_valuetype argvType = ImageNapiUtils::getType(env, (args.argv)[i]); | ||
| 212 | + if (argvType != napi_number) { | ||
| 213 | + errMsg = "Invailed arg "; | ||
| 214 | + errMsg.append(std::to_string(i)).append(" type ").append(std::to_string(argvType)); | ||
| 215 | + return false; | ||
| 216 | + } | ||
| 217 | + | ||
| 218 | + status = napi_get_value_int32(env, (args.argv)[i], &((args.args)[i])); | ||
| 219 | + if (status != napi_ok) { | ||
| 220 | + errMsg = "fail to get arg "; | ||
| 221 | + errMsg.append(std::to_string(i)).append(" : ").append(std::to_string(status)); | ||
| 222 | + return false; | ||
| 223 | + } | ||
| 224 | + } | ||
| 225 | + return true; | ||
| 226 | +} | ||
| 227 | + | ||
| 180 | napi_value ImageReceiverNapi::Constructor(napi_env env, napi_callback_info info) | 228 | napi_value ImageReceiverNapi::Constructor(napi_env env, napi_callback_info info) |
| 181 | { | 229 | { |
| 182 | napi_value undefineVar = nullptr; | 230 | napi_value undefineVar = nullptr; |
| 183 | napi_get_undefined(env, &undefineVar); | 231 | napi_get_undefined(env, &undefineVar); |
| 184 | 232 | ||
| 185 | - napi_status status; | ||
| 186 | - napi_value thisVar = nullptr; | ||
| 187 | - | ||
| 188 | IMAGE_FUNCTION_IN(); | 233 | IMAGE_FUNCTION_IN(); |
| 189 | - status = napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); | 234 | + std::string errMsg; |
| 190 | - if (status == napi_ok && thisVar != nullptr) { | 235 | + ImageReceiverInputArgs inputArgs; |
| 191 | - std::unique_ptr<ImageReceiverNapi> reference = std::make_unique<ImageReceiverNapi>(); | 236 | + inputArgs.argc = ARGS4; |
| 192 | - if (reference != nullptr) { | 237 | + if (!parseImageReceiverArgs(env, info, inputArgs, errMsg) || inputArgs.thisVar == nullptr) { |
| 193 | - reference->env_ = env; | 238 | + IMAGE_ERR("Failure. %{public}s", errMsg.c_str()); |
| 194 | - reference->imageReceiver_ = staticInstance_; | 239 | + return undefineVar; |
| 195 | - status = napi_wrap(env, thisVar, reinterpret_cast<void *>(reference.get()), | ||
| 196 | - ImageReceiverNapi::Destructor, nullptr, nullptr); | ||
| 197 | - if (status == napi_ok) { | ||
| 198 | - IMAGE_FUNCTION_OUT(); | ||
| 199 | - reference.release(); | ||
| 200 | - return thisVar; | ||
| 201 | - } else { | ||
| 202 | - IMAGE_ERR("Failure wrapping js to native napi"); | ||
| 203 | - } | ||
| 204 | - } | ||
| 205 | } | 240 | } |
| 206 | - | 241 | + auto reference = std::make_unique<ImageReceiverNapi>(); |
| 242 | + reference->env_ = env; | ||
| 243 | + reference->imageReceiver_ = ImageReceiver::CreateImageReceiver((inputArgs.args)[PARAM0], | ||
| 244 | + (inputArgs.args)[PARAM1], (inputArgs.args)[PARAM2], (inputArgs.args)[PARAM3]); | ||
| 245 | + if (reference->imageReceiver_ == nullptr) { | ||
| 246 | + IMAGE_ERR("Create native image receiver failed"); | ||
| 247 | + return undefineVar; | ||
| 248 | + } | ||
| 249 | + napi_status status = napi_wrap(env, inputArgs.thisVar, reinterpret_cast<void *>(reference.get()), | ||
| 250 | + ImageReceiverNapi::Destructor, nullptr, nullptr); | ||
| 251 | + if (status == napi_ok) { | ||
| 252 | + reference.release(); | ||
| 253 | + return inputArgs.thisVar; | ||
| 254 | + } | ||
| 255 | + IMAGE_ERR("Failure wrapping js to native napi"); | ||
| 207 | return undefineVar; | 256 | return undefineVar; |
| 208 | } | 257 | } |
| 209 | 258 | ||
| @@ -221,54 +270,62 @@ static bool checkFormat(int32_t format) | |||
| 221 | return false; | 270 | return false; |
| 222 | } | 271 | } |
| 223 | 272 | ||
| 273 | +napi_value ImageReceiverNapi::CreateImageReceiverJsObject(napi_env env, struct ImageReceiverCreateArgs args) | ||
| 274 | +{ | ||
| 275 | + napi_status status; | ||
| 276 | + napi_value constructor = nullptr; | ||
| 277 | + napi_value result = nullptr; | ||
| 278 | + ImageReceiverInputArgs inputArgs; | ||
| 279 | + inputArgs.argc = ARGS4; | ||
| 280 | + | ||
| 281 | + IMAGE_FUNCTION_IN(); | ||
| 282 | + if (!checkFormat(args.format)) { | ||
| 283 | + IMAGE_ERR("Invailed type"); | ||
| 284 | + return nullptr; | ||
| 285 | + } | ||
| 286 | + napi_create_int32(env, args.width, &(inputArgs.argv[PARAM0])); | ||
| 287 | + napi_create_int32(env, args.height, &(inputArgs.argv[PARAM1])); | ||
| 288 | + napi_create_int32(env, args.format, &(inputArgs.argv[PARAM2])); | ||
| 289 | + napi_create_int32(env, args.capicity, &(inputArgs.argv[PARAM3])); | ||
| 290 | + status = napi_get_reference_value(env, sConstructor_, &constructor); | ||
| 291 | + if (status != napi_ok || constructor == nullptr) { | ||
| 292 | + IMAGE_ERR("Failed to get reference of constructor"); | ||
| 293 | + return nullptr; | ||
| 294 | + } | ||
| 295 | + | ||
| 296 | + status = napi_new_instance(env, constructor, inputArgs.argc, inputArgs.argv, &result); | ||
| 297 | + if (status != napi_ok || result == nullptr) { | ||
| 298 | + IMAGE_ERR("New instance could not be obtained"); | ||
| 299 | + return nullptr; | ||
| 300 | + } | ||
| 301 | + | ||
| 302 | + IMAGE_FUNCTION_OUT(); | ||
| 303 | + return result; | ||
| 304 | +} | ||
| 305 | + | ||
| 224 | napi_value ImageReceiverNapi::JSCreateImageReceiver(napi_env env, napi_callback_info info) | 306 | napi_value ImageReceiverNapi::JSCreateImageReceiver(napi_env env, napi_callback_info info) |
| 225 | { | 307 | { |
| 226 | napi_status status; | 308 | napi_status status; |
| 227 | - napi_value constructor = nullptr, result = nullptr, thisVar = nullptr; | 309 | + napi_value constructor = nullptr, result = nullptr; |
| 228 | - size_t argc = ARGS4; | 310 | + ImageReceiverInputArgs inputArgs; |
| 229 | - napi_value argv[ARGS4] = {0}; | 311 | + inputArgs.argc = ARGS4; |
| 230 | - int32_t args[ARGS4] = {0}; | ||
| 231 | 312 | ||
| 232 | IMAGE_FUNCTION_IN(); | 313 | IMAGE_FUNCTION_IN(); |
| 233 | napi_get_undefined(env, &result); | 314 | napi_get_undefined(env, &result); |
| 234 | 315 | ||
| 235 | - status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); | 316 | + std::string errMsg; |
| 236 | - if (status != napi_ok) { | 317 | + if (!parseImageReceiverArgs(env, info, inputArgs, errMsg)) { |
| 237 | - IMAGE_ERR("fail to napi_get_cb_info %{public}d", status); | 318 | + return ImageNapiUtils::ThrowExceptionError(env, static_cast<int32_t>(napi_invalid_arg), errMsg); |
| 238 | - return result; | ||
| 239 | } | 319 | } |
| 240 | 320 | ||
| 241 | - if (argc != ARGS4) { | 321 | + if (!checkFormat(inputArgs.args[PARAM2])) { |
| 242 | - std::string errMsg = "Invailed arg counts "; | ||
| 243 | - return ImageNapiUtils::ThrowExceptionError(env, static_cast<int32_t>(napi_invalid_arg), | ||
| 244 | - errMsg.append(std::to_string(argc))); | ||
| 245 | - } | ||
| 246 | - | ||
| 247 | - for (size_t i = PARAM0; i < argc; i++) { | ||
| 248 | - napi_valuetype argvType = ImageNapiUtils::getType(env, argv[i]); | ||
| 249 | - if (argvType != napi_number) { | ||
| 250 | - std::string errMsg = "Invailed arg "; | ||
| 251 | - return ImageNapiUtils::ThrowExceptionError(env, static_cast<int32_t>(napi_invalid_arg), | ||
| 252 | - errMsg.append(std::to_string(i)).append(" type ").append(std::to_string(argvType))); | ||
| 253 | - } | ||
| 254 | - | ||
| 255 | - status = napi_get_value_int32(env, argv[i], &(args[i])); | ||
| 256 | - if (status != napi_ok) { | ||
| 257 | - std::string errMsg = "fail to get arg "; | ||
| 258 | - return ImageNapiUtils::ThrowExceptionError(env, static_cast<int32_t>(napi_invalid_arg), | ||
| 259 | - errMsg.append(std::to_string(i)).append(" : ").append(std::to_string(status))); | ||
| 260 | - } | ||
| 261 | - } | ||
| 262 | - | ||
| 263 | - if (!checkFormat(args[PARAM2])) { | ||
| 264 | return ImageNapiUtils::ThrowExceptionError(env, | 322 | return ImageNapiUtils::ThrowExceptionError(env, |
| 265 | static_cast<int32_t>(napi_invalid_arg), "Invailed type"); | 323 | static_cast<int32_t>(napi_invalid_arg), "Invailed type"); |
| 266 | } | 324 | } |
| 267 | 325 | ||
| 268 | status = napi_get_reference_value(env, sConstructor_, &constructor); | 326 | status = napi_get_reference_value(env, sConstructor_, &constructor); |
| 269 | if (IMG_IS_OK(status)) { | 327 | if (IMG_IS_OK(status)) { |
| 270 | - staticInstance_ = ImageReceiver::CreateImageReceiver(args[PARAM0], args[PARAM1], args[PARAM2], args[PARAM3]); | 328 | + status = napi_new_instance(env, constructor, inputArgs.argc, inputArgs.argv, &result); |
| 271 | - status = napi_new_instance(env, constructor, 0, nullptr, &result); | ||
| 272 | if (status == napi_ok) { | 329 | if (status == napi_ok) { |
| 273 | IMAGE_FUNCTION_OUT(); | 330 | IMAGE_FUNCTION_OUT(); |
| 274 | return result; | 331 | return result; |
| @@ -622,7 +679,7 @@ napi_value ImageReceiverNapi::JsGetReceivingSurfaceId(napi_env env, napi_callbac | |||
| 622 | return JSCommonProcess(args); | 679 | return JSCommonProcess(args); |
| 623 | } | 680 | } |
| 624 | 681 | ||
| 625 | -#ifdef IMAGE_DEBUG_FLAG | 682 | +#ifdef IMAGE_SAVE_BUFFER_TO_PIC |
| 626 | static void DoCallBackTest(OHOS::sptr<OHOS::SurfaceBuffer> surfaceBuffer1) | 683 | static void DoCallBackTest(OHOS::sptr<OHOS::SurfaceBuffer> surfaceBuffer1) |
| 627 | { | 684 | { |
| 628 | if (surfaceBuffer1 == nullptr) { | 685 | if (surfaceBuffer1 == nullptr) { |
| @@ -646,12 +703,19 @@ static void DoCallBackTest(OHOS::sptr<OHOS::SurfaceBuffer> surfaceBuffer1) | |||
| 646 | opts.editable = true; | 703 | opts.editable = true; |
| 647 | IMAGE_ERR("DoCallBackTest Width %{public}d", opts.size.width); | 704 | IMAGE_ERR("DoCallBackTest Width %{public}d", opts.size.width); |
| 648 | IMAGE_ERR("DoCallBackTest Height %{public}d", opts.size.height); | 705 | IMAGE_ERR("DoCallBackTest Height %{public}d", opts.size.height); |
| 649 | - | ||
| 650 | int fd = open("/data/receiver/test.jpg", O_RDWR | O_CREAT); | 706 | int fd = open("/data/receiver/test.jpg", O_RDWR | O_CREAT); |
| 651 | imageReceiver1->SaveBufferAsImage(fd, surfaceBuffer1, opts); | 707 | imageReceiver1->SaveBufferAsImage(fd, surfaceBuffer1, opts); |
| 652 | - | ||
| 653 | } | 708 | } |
| 654 | 709 | ||
| 710 | +static void FailedCallbackRoutine(napi_env env, Context &context, uint32_t errCode) | ||
| 711 | +{ | ||
| 712 | + napi_value result = nullptr; | ||
| 713 | + napi_get_undefined(env, &result); | ||
| 714 | + if (context != nullptr) { | ||
| 715 | + context->status = ERR_IMAGE_INIT_ABNORMAL; | ||
| 716 | + } | ||
| 717 | + CommonCallbackRoutine(env, context, result); | ||
| 718 | +} | ||
| 655 | napi_value ImageReceiverNapi::JsReadLatestImage(napi_env env, napi_callback_info info) | 719 | napi_value ImageReceiverNapi::JsReadLatestImage(napi_env env, napi_callback_info info) |
| 656 | { | 720 | { |
| 657 | IMAGE_FUNCTION_IN(); | 721 | IMAGE_FUNCTION_IN(); |
| @@ -666,31 +730,33 @@ napi_value ImageReceiverNapi::JsReadLatestImage(napi_env env, napi_callback_info | |||
| 666 | 730 | ||
| 667 | args.callBack = [](napi_env env, napi_status status, Context context) { | 731 | args.callBack = [](napi_env env, napi_status status, Context context) { |
| 668 | IMAGE_LINE_IN(); | 732 | IMAGE_LINE_IN(); |
| 669 | - napi_value result = nullptr; | ||
| 670 | - napi_get_undefined(env, &result); | ||
| 671 | - | ||
| 672 | auto native = context->constructor_->imageReceiver_; | 733 | auto native = context->constructor_->imageReceiver_; |
| 673 | if (native == nullptr) { | 734 | if (native == nullptr) { |
| 674 | IMAGE_ERR("Native instance is nullptr"); | 735 | IMAGE_ERR("Native instance is nullptr"); |
| 675 | - context->status = ERR_IMAGE_INIT_ABNORMAL; | 736 | + FailedCallbackRoutine(env, context, ERR_IMAGE_INIT_ABNORMAL); |
| 676 | - } else { | 737 | + return; |
| 677 | - auto surfacebuffer = native->ReadLastImage(); | ||
| 678 | - | ||
| 679 | - if (context->constructor_->isCallBackTest) { | ||
| 680 | - context->constructor_->isCallBackTest = false; | ||
| 681 | - DoCallBackTest(surfacebuffer); | ||
| 682 | - } | ||
| 683 | - | ||
| 684 | - result = ImageNapi::Create(env, surfacebuffer, native); | ||
| 685 | - if (result == nullptr) { | ||
| 686 | - IMAGE_ERR("ImageNapi Create failed"); | ||
| 687 | - context->status = ERR_IMAGE_INIT_ABNORMAL; | ||
| 688 | - napi_get_undefined(env, &result); | ||
| 689 | - } else { | ||
| 690 | - context->status = SUCCESS; | ||
| 691 | - } | ||
| 692 | } | 738 | } |
| 693 | - | 739 | + auto image = native->LastNativeImage(); |
| 740 | + if (image == nullptr) { | ||
| 741 | + IMAGE_ERR("LastNativeImage is nullptr"); | ||
| 742 | + FailedCallbackRoutine(env, context, ERR_IMAGE_INIT_ABNORMAL); | ||
| 743 | + return; | ||
| 744 | + } | ||
| 745 | + | ||
| 746 | + if (context->constructor_->isCallBackTest) { | ||
| 747 | + context->constructor_->isCallBackTest = false; | ||
| 748 | + | ||
| 749 | + DoCallBackTest(image->GetBuffer()); | ||
| 750 | + | ||
| 751 | + } | ||
| 752 | + | ||
| 753 | + napi_value result = ImageNapi::Create(env, image); | ||
| 754 | + if (result == nullptr) { | ||
| 755 | + IMAGE_ERR("ImageNapi Create is nullptr"); | ||
| 756 | + FailedCallbackRoutine(env, context, ERR_IMAGE_INIT_ABNORMAL); | ||
| 757 | + return; | ||
| 758 | + } | ||
| 759 | + context->status = SUCCESS; | ||
| 694 | IMAGE_LINE_OUT(); | 760 | IMAGE_LINE_OUT(); |
| 695 | CommonCallbackRoutine(env, context, result); | 761 | CommonCallbackRoutine(env, context, result); |
| 696 | }; | 762 | }; |
| @@ -712,31 +778,33 @@ napi_value ImageReceiverNapi::JsReadNextImage(napi_env env, napi_callback_info i | |||
| 712 | 778 | ||
| 713 | args.callBack = [](napi_env env, napi_status status, Context context) { | 779 | args.callBack = [](napi_env env, napi_status status, Context context) { |
| 714 | IMAGE_LINE_IN(); | 780 | IMAGE_LINE_IN(); |
| 715 | - napi_value result = nullptr; | ||
| 716 | - napi_get_undefined(env, &result); | ||
| 717 | - | ||
| 718 | auto native = context->constructor_->imageReceiver_; | 781 | auto native = context->constructor_->imageReceiver_; |
| 719 | if (native == nullptr) { | 782 | if (native == nullptr) { |
| 720 | IMAGE_ERR("Native instance is nullptr"); | 783 | IMAGE_ERR("Native instance is nullptr"); |
| 721 | - context->status = ERR_IMAGE_INIT_ABNORMAL; | 784 | + FailedCallbackRoutine(env, context, ERR_IMAGE_INIT_ABNORMAL); |
| 722 | - } else { | 785 | + return; |
| 723 | - auto surfacebuffer = native->ReadNextImage(); | ||
| 724 | - | ||
| 725 | - if (context->constructor_->isCallBackTest) { | ||
| 726 | - context->constructor_->isCallBackTest = false; | ||
| 727 | - DoCallBackTest(surfacebuffer); | ||
| 728 | - } | ||
| 729 | - | ||
| 730 | - result = ImageNapi::Create(env, surfacebuffer, native); | ||
| 731 | - if (result == nullptr) { | ||
| 732 | - IMAGE_ERR("ImageNapi Create failed"); | ||
| 733 | - context->status = ERR_IMAGE_INIT_ABNORMAL; | ||
| 734 | - napi_get_undefined(env, &result); | ||
| 735 | - } else { | ||
| 736 | - context->status = SUCCESS; | ||
| 737 | - } | ||
| 738 | } | 786 | } |
| 739 | - | 787 | + auto image = native->NextNativeImage(); |
| 788 | + if (image == nullptr) { | ||
| 789 | + IMAGE_ERR("NextNativeImage is nullptr"); | ||
| 790 | + FailedCallbackRoutine(env, context, ERR_IMAGE_INIT_ABNORMAL); | ||
| 791 | + return; | ||
| 792 | + } | ||
| 793 | + | ||
| 794 | + if (context->constructor_->isCallBackTest) { | ||
| 795 | + context->constructor_->isCallBackTest = false; | ||
| 796 | + | ||
| 797 | + DoCallBackTest(image->GetBuffer()); | ||
| 798 | + | ||
| 799 | + } | ||
| 800 | + | ||
| 801 | + napi_value result = ImageNapi::Create(env, image); | ||
| 802 | + if (result == nullptr) { | ||
| 803 | + IMAGE_ERR("ImageNapi Create is nullptr"); | ||
| 804 | + FailedCallbackRoutine(env, context, ERR_IMAGE_INIT_ABNORMAL); | ||
| 805 | + return; | ||
| 806 | + } | ||
| 807 | + context->status = SUCCESS; | ||
| 740 | IMAGE_LINE_OUT(); | 808 | IMAGE_LINE_OUT(); |
| 741 | CommonCallbackRoutine(env, context, result); | 809 | CommonCallbackRoutine(env, context, result); |
| 742 | }; | 810 | }; |
| @@ -0,0 +1,56 @@ | |||
| 1 | +# Copyright (C) 2022 Huawei Device Co., Ltd. | ||
| 2 | +# Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 3 | +# you may not use this file except in compliance with the License. | ||
| 4 | +# You may obtain a copy of the License at | ||
| 5 | +# | ||
| 6 | +# http://www.apache.org/licenses/LICENSE-2.0 | ||
| 7 | +# | ||
| 8 | +# Unless required by applicable law or agreed to in writing, software | ||
| 9 | +# distributed under the License is distributed on an "AS IS" BASIS, | ||
| 10 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 11 | +# See the License for the specific language governing permissions and | ||
| 12 | +# limitations under the License. | ||
| 13 | + | ||
| 14 | +import("//build/ohos.gni") | ||
| 15 | + | ||
| 16 | +SEPARATOR = "/" | ||
| 17 | +BASE_DIR = "$SEPARATOR/foundation" | ||
| 18 | +THIRD_DIR = "$SEPARATOR/third_party" | ||
| 19 | + | ||
| 20 | +config("native_public_config") { | ||
| 21 | + include_dirs = [ | ||
| 22 | + "include", | ||
| 23 | + "$BASE_DIR/arkui/napi/interfaces/inner_api", | ||
| 24 | + "$BASE_DIR/arkui/napi/interfaces/kits", | ||
| 25 | + "$BASE_DIR/multimedia/image_framework/interfaces/kits/native/include", | ||
| 26 | + "$THIRD_DIR/node/src", | ||
| 27 | + ] | ||
| 28 | +} | ||
| 29 | + | ||
| 30 | +ohos_shared_library("image_ndk") { | ||
| 31 | + sanitize = { | ||
| 32 | + cfi = true | ||
| 33 | + debug = false | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | + sources = [ "image_mdk.cpp" ] | ||
| 37 | + public_configs = [ ":native_public_config" ] | ||
| 38 | + external_deps = [ "multimedia_image_framework:image" ] | ||
| 39 | + | ||
| 40 | + subsystem_name = "multimedia" | ||
| 41 | + part_name = "multimedia_image_framework" | ||
| 42 | +} | ||
| 43 | + | ||
| 44 | +ohos_shared_library("image_receiver_ndk") { | ||
| 45 | + sanitize = { | ||
| 46 | + cfi = true | ||
| 47 | + debug = false | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + sources = [ "image_receiver_mdk.cpp" ] | ||
| 51 | + public_configs = [ ":native_public_config" ] | ||
| 52 | + external_deps = [ "multimedia_image_framework:image" ] | ||
| 53 | + | ||
| 54 | + subsystem_name = "multimedia" | ||
| 55 | + part_name = "multimedia_image_framework" | ||
| 56 | +} | ||
| @@ -0,0 +1,106 @@ | |||
| 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 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | +namespace OHOS { | ||
| 22 | +namespace Media { | ||
| 23 | + | ||
| 24 | +extern "C" { | ||
| 25 | + | ||
| 26 | +struct ImageNative_ { | ||
| 27 | + ImageNapi* napi = nullptr; | ||
| 28 | +}; | ||
| 29 | + | ||
| 30 | +MIDK_EXPORT | ||
| 31 | +ImageNative* OH_Image_InitImageNative(napi_env env, napi_value source) | ||
| 32 | +{ | ||
| 33 | + ImageNapi* napi = ImageNapi_Unwrap(env, source); | ||
| 34 | + if (napi == nullptr) { | ||
| 35 | + return nullptr; | ||
| 36 | + } | ||
| 37 | + std::unique_ptr<ImageNative> result = std::make_unique<ImageNative>(); | ||
| 38 | + result->napi = napi; | ||
| 39 | + return result.release(); | ||
| 40 | +} | ||
| 41 | + | ||
| 42 | +MIDK_EXPORT | ||
| 43 | +int32_t OH_Image_ClipRect(const ImageNative* native, struct OhosImageRect* rect) | ||
| 44 | +{ | ||
| 45 | + if (native == nullptr || native->napi == nullptr) { | ||
| 46 | + return OHOS_IMAGE_RESULT_BAD_PARAMETER; | ||
| 47 | + } | ||
| 48 | + ImageNapiArgs args; | ||
| 49 | + args.outRect = rect; | ||
| 50 | + auto res = ImageNapiNativeCtxCall(CTX_FUNC_IMAGE_CLIP_RECT, native->napi, &args); | ||
| 51 | + return res; | ||
| 52 | +} | ||
| 53 | + | ||
| 54 | +MIDK_EXPORT | ||
| 55 | +int32_t OH_Image_Size(const ImageNative* native, struct OhosImageSize* size) | ||
| 56 | +{ | ||
| 57 | + if (native == nullptr || native->napi == nullptr) { | ||
| 58 | + return OHOS_IMAGE_RESULT_BAD_PARAMETER; | ||
| 59 | + } | ||
| 60 | + ImageNapiArgs args; | ||
| 61 | + args.outSize = size; | ||
| 62 | + auto res = ImageNapiNativeCtxCall(CTX_FUNC_IMAGE_SIZE, native->napi, &args); | ||
| 63 | + return res; | ||
| 64 | +} | ||
| 65 | + | ||
| 66 | +MIDK_EXPORT | ||
| 67 | +int32_t OH_Image_Format(const ImageNative* native, int32_t* format) | ||
| 68 | +{ | ||
| 69 | + if (native == nullptr || native->napi == nullptr) { | ||
| 70 | + return OHOS_IMAGE_RESULT_BAD_PARAMETER; | ||
| 71 | + } | ||
| 72 | + ImageNapiArgs args; | ||
| 73 | + args.outNum0 = format; | ||
| 74 | + auto res = ImageNapiNativeCtxCall(CTX_FUNC_IMAGE_FORMAT, native->napi, &args); | ||
| 75 | + return res; | ||
| 76 | +} | ||
| 77 | + | ||
| 78 | +MIDK_EXPORT | ||
| 79 | +int32_t OH_Image_GetComponent(const ImageNative* native, int32_t componentType, | ||
| 80 | + struct OhosImageComponent* componentNative) | ||
| 81 | +{ | ||
| 82 | + if (native == nullptr || native->napi == nullptr) { | ||
| 83 | + return OHOS_IMAGE_RESULT_BAD_PARAMETER; | ||
| 84 | + } | ||
| 85 | + ImageNapiArgs args; | ||
| 86 | + args.inNum0 = componentType; | ||
| 87 | + args.outComponent = componentNative; | ||
| 88 | + auto res = ImageNapiNativeCtxCall(CTX_FUNC_IMAGE_GET_COMPONENT, native->napi, &args); | ||
| 89 | + return res; | ||
| 90 | +} | ||
| 91 | + | ||
| 92 | +MIDK_EXPORT | ||
| 93 | +int32_t OH_Image_Release(ImageNative* native) | ||
| 94 | +{ | ||
| 95 | + if (native != nullptr) { | ||
| 96 | + delete native; | ||
| 97 | + native = nullptr; | ||
| 98 | + } | ||
| 99 | + return OHOS_IMAGE_RESULT_SUCCESS; | ||
| 100 | +} | ||
| 101 | + | ||
| 102 | + | ||
| 103 | +}; | ||
| 104 | + | ||
| 105 | +} // namespace Media | ||
| 106 | +} // namespace OHOS | ||
| @@ -0,0 +1,150 @@ | |||
| 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 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | +namespace OHOS { | ||
| 22 | +namespace Media { | ||
| 23 | + | ||
| 24 | +extern "C" { | ||
| 25 | + | ||
| 26 | +struct ImageReceiverNative_ { | ||
| 27 | + ImageReceiverNapi* napi = nullptr; | ||
| 28 | + napi_env env = nullptr; | ||
| 29 | +}; | ||
| 30 | + | ||
| 31 | +MIDK_EXPORT | ||
| 32 | +ImageReceiverNative* OH_Image_Receiver_InitImageReceiverNative(napi_env env, napi_value source) | ||
| 33 | +{ | ||
| 34 | + ImageReceiverNapi* napi = ImageReceiver_Unwrap(env, source); | ||
| 35 | + if (napi == nullptr) { | ||
| 36 | + return nullptr; | ||
| 37 | + } | ||
| 38 | + std::unique_ptr<ImageReceiverNative> result = std::make_unique<ImageReceiverNative>(); | ||
| 39 | + result->napi = napi; | ||
| 40 | + result->env = env; | ||
| 41 | + return result.release(); | ||
| 42 | +} | ||
| 43 | + | ||
| 44 | +MIDK_EXPORT | ||
| 45 | +int32_t OH_Image_Receiver_CreateImageReceiver(napi_env env, | ||
| 46 | + struct OhosImageReceiverInfo info, napi_value* res) | ||
| 47 | +{ | ||
| 48 | + ImageReceiverArgs args; | ||
| 49 | + args.inNum0 = info.width; | ||
| 50 | + args.inNum1 = info.height; | ||
| 51 | + args.inNum2 = info.format; | ||
| 52 | + args.inNum3 = info.capicity; | ||
| 53 | + args.outValue = res; | ||
| 54 | + return ImageReceiverNativeEnvCall(ENV_FUNC_IMAGE_RECEIVER_CREATE, env, &args); | ||
| 55 | +} | ||
| 56 | + | ||
| 57 | +MIDK_EXPORT | ||
| 58 | +int32_t OH_Image_Receiver_GetReceivingSurfaceId(const ImageReceiverNative* native, char* id, size_t len) | ||
| 59 | +{ | ||
| 60 | + if (native == nullptr || native->napi == nullptr) { | ||
| 61 | + return OHOS_IMAGE_RESULT_BAD_PARAMETER; | ||
| 62 | + } | ||
| 63 | + ImageReceiverArgs args; | ||
| 64 | + args.id = id; | ||
| 65 | + args.inLen = len; | ||
| 66 | + return ImageReceiverNativeCtxCall(CTX_FUNC_IMAGE_RECEIVER_GET_RECEIVER_ID, native->napi, &args); | ||
| 67 | +} | ||
| 68 | + | ||
| 69 | +MIDK_EXPORT | ||
| 70 | +int32_t OH_Image_Receiver_ReadLatestImage(const ImageReceiverNative* native, napi_value* image) | ||
| 71 | +{ | ||
| 72 | + if (native == nullptr || native->napi == nullptr || native->env == nullptr) { | ||
| 73 | + return OHOS_IMAGE_RESULT_BAD_PARAMETER; | ||
| 74 | + } | ||
| 75 | + ImageReceiverArgs args; | ||
| 76 | + args.outValue = image; | ||
| 77 | + args.inEnv = native->env; | ||
| 78 | + return ImageReceiverNativeCtxCall(CTX_FUNC_IMAGE_RECEIVER_READ_LATEST_IMAGE, native->napi, &args); | ||
| 79 | +} | ||
| 80 | + | ||
| 81 | +MIDK_EXPORT | ||
| 82 | +int32_t OH_Image_Receiver_ReadNextImage(const ImageReceiverNative* native, napi_value* image) | ||
| 83 | +{ | ||
| 84 | + if (native == nullptr || native->napi == nullptr || native->env == nullptr) { | ||
| 85 | + return OHOS_IMAGE_RESULT_BAD_PARAMETER; | ||
| 86 | + } | ||
| 87 | + ImageReceiverArgs args; | ||
| 88 | + args.outValue = image; | ||
| 89 | + args.inEnv = native->env; | ||
| 90 | + return ImageReceiverNativeCtxCall(CTX_FUNC_IMAGE_RECEIVER_READ_NEXT_IMAGE, native->napi, &args); | ||
| 91 | +} | ||
| 92 | + | ||
| 93 | +MIDK_EXPORT | ||
| 94 | +int32_t OH_Image_Receiver_On(const ImageReceiverNative* native, OH_Image_Receiver_On_Callback callback) | ||
| 95 | +{ | ||
| 96 | + if (native == nullptr || native->napi == nullptr || callback == nullptr) { | ||
| 97 | + return OHOS_IMAGE_RESULT_BAD_PARAMETER; | ||
| 98 | + } | ||
| 99 | + ImageReceiverArgs args; | ||
| 100 | + args.callback = callback; | ||
| 101 | + return ImageReceiverNativeCtxCall(CTX_FUNC_IMAGE_RECEIVER_ON, native->napi, &args); | ||
| 102 | +} | ||
| 103 | + | ||
| 104 | +MIDK_EXPORT | ||
| 105 | +int32_t OH_Image_Receiver_GetSize(const ImageReceiverNative* native, struct OhosImageSize* size) | ||
| 106 | +{ | ||
| 107 | + if (native == nullptr || native->napi == nullptr) { | ||
| 108 | + return OHOS_IMAGE_RESULT_BAD_PARAMETER; | ||
| 109 | + } | ||
| 110 | + ImageReceiverArgs args; | ||
| 111 | + args.outSize = size; | ||
| 112 | + return ImageReceiverNativeCtxCall(CTX_FUNC_IMAGE_RECEIVER_GET_SIZE, native->napi, &args); | ||
| 113 | +} | ||
| 114 | + | ||
| 115 | +MIDK_EXPORT | ||
| 116 | +int32_t OH_Image_Receiver_GetCapacity(const ImageReceiverNative* native, int32_t* capacity) | ||
| 117 | +{ | ||
| 118 | + if (native == nullptr || native->napi == nullptr) { | ||
| 119 | + return OHOS_IMAGE_RESULT_BAD_PARAMETER; | ||
| 120 | + } | ||
| 121 | + ImageReceiverArgs args; | ||
| 122 | + args.outNum0 = capacity; | ||
| 123 | + return ImageReceiverNativeCtxCall(CTX_FUNC_IMAGE_RECEIVER_GET_CAPACITY, native->napi, &args); | ||
| 124 | +} | ||
| 125 | + | ||
| 126 | +MIDK_EXPORT | ||
| 127 | +int32_t OH_Image_Receiver_GetFormat(const ImageReceiverNative* native, int32_t* format) | ||
| 128 | +{ | ||
| 129 | + if (native == nullptr || native->napi == nullptr) { | ||
| 130 | + return OHOS_IMAGE_RESULT_BAD_PARAMETER; | ||
| 131 | + } | ||
| 132 | + ImageReceiverArgs args; | ||
| 133 | + args.outNum0 = format; | ||
| 134 | + return ImageReceiverNativeCtxCall(CTX_FUNC_IMAGE_RECEIVER_GET_FORMAT, native->napi, &args); | ||
| 135 | +} | ||
| 136 | + | ||
| 137 | +MIDK_EXPORT | ||
| 138 | +int32_t OH_Image_Receiver_Release(ImageReceiverNative* native) | ||
| 139 | +{ | ||
| 140 | + if (native != nullptr) { | ||
| 141 | + delete native; | ||
| 142 | + native = nullptr; | ||
| 143 | + } | ||
| 144 | + return OHOS_IMAGE_RESULT_SUCCESS; | ||
| 145 | +} | ||
| 146 | + | ||
| 147 | +}; | ||
| 148 | + | ||
| 149 | +} // namespace Media | ||
| 150 | +} // namespace OHOS | ||
| @@ -0,0 +1,54 @@ | |||
| 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 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | +namespace OHOS { | ||
| 25 | +namespace Media { | ||
| 26 | + | ||
| 27 | +extern "C" { | ||
| 28 | + | ||
| 29 | + | ||
| 30 | +struct ImageNapiArgs { | ||
| 31 | + int32_t inNum0; | ||
| 32 | + struct OhosImageRect* outRect; | ||
| 33 | + struct OhosImageSize* outSize; | ||
| 34 | + int32_t* outNum0; | ||
| 35 | + napi_value* outVal; | ||
| 36 | + struct OhosImageComponent* outComponent; | ||
| 37 | +}; | ||
| 38 | + | ||
| 39 | +enum { | ||
| 40 | + CTX_FUNC_IMAGE_CLIP_RECT, | ||
| 41 | + CTX_FUNC_IMAGE_SIZE, | ||
| 42 | + CTX_FUNC_IMAGE_FORMAT, | ||
| 43 | + CTX_FUNC_IMAGE_GET_COMPONENT | ||
| 44 | +}; | ||
| 45 | + | ||
| 46 | +ImageNapi* ImageNapi_Unwrap(napi_env env, napi_value value); | ||
| 47 | +int32_t ImageNapiNativeCtxCall(int32_t mode, ImageNapi* native, struct ImageNapiArgs* args); | ||
| 48 | + | ||
| 49 | +}; | ||
| 50 | + | ||
| 51 | +} // namespace Media | ||
| 52 | +} // namespace OHOS | ||
| 53 | + | ||
| 54 | + | ||
| @@ -0,0 +1,63 @@ | |||
| 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 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | +namespace OHOS { | ||
| 25 | +namespace Media { | ||
| 26 | + | ||
| 27 | +extern "C" { | ||
| 28 | + | ||
| 29 | + | ||
| 30 | +struct ImageReceiverArgs { | ||
| 31 | + char* id; | ||
| 32 | + size_t inLen; | ||
| 33 | + int32_t inNum0; | ||
| 34 | + int32_t inNum1; | ||
| 35 | + int32_t inNum2; | ||
| 36 | + int32_t inNum3; | ||
| 37 | + napi_env inEnv; | ||
| 38 | + OH_Image_Receiver_On_Callback callback; | ||
| 39 | + napi_value* outValue; | ||
| 40 | + int32_t* outNum0; | ||
| 41 | + struct OhosImageSize* outSize; | ||
| 42 | +}; | ||
| 43 | + | ||
| 44 | +enum { | ||
| 45 | + ENV_FUNC_IMAGE_RECEIVER_CREATE, | ||
| 46 | + CTX_FUNC_IMAGE_RECEIVER_GET_RECEIVER_ID, | ||
| 47 | + CTX_FUNC_IMAGE_RECEIVER_READ_LATEST_IMAGE, | ||
| 48 | + CTX_FUNC_IMAGE_RECEIVER_READ_NEXT_IMAGE, | ||
| 49 | + CTX_FUNC_IMAGE_RECEIVER_ON, | ||
| 50 | + CTX_FUNC_IMAGE_RECEIVER_GET_SIZE, | ||
| 51 | + CTX_FUNC_IMAGE_RECEIVER_GET_CAPACITY, | ||
| 52 | + CTX_FUNC_IMAGE_RECEIVER_GET_FORMAT, | ||
| 53 | +}; | ||
| 54 | + | ||
| 55 | +ImageReceiverNapi* ImageReceiver_Unwrap(napi_env env, napi_value value); | ||
| 56 | +int32_t ImageReceiverNativeEnvCall(int32_t mode, napi_env env, struct ImageReceiverArgs* args); | ||
| 57 | +int32_t ImageReceiverNativeCtxCall(int32_t mode, ImageReceiverNapi* native, struct ImageReceiverArgs* args); | ||
| 58 | + | ||
| 59 | +}; | ||
| 60 | + | ||
| 61 | +} // namespace Media | ||
| 62 | +} // namespace OHOS | ||
| 63 | + | ||
| @@ -0,0 +1,40 @@ | |||
| 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 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | +namespace OHOS { | ||
| 23 | +namespace Media { | ||
| 24 | +class ImageReceiverNapiListener : public SurfaceBufferAvaliableListener { | ||
| 25 | +public: | ||
| 26 | + ~ImageReceiverNapiListener() override | ||
| 27 | + { | ||
| 28 | + callBack = nullptr; | ||
| 29 | + } | ||
| 30 | + void OnSurfaceBufferAvaliable() __attribute__((no_sanitize("cfi"))) override | ||
| 31 | + { | ||
| 32 | + if (callBack != nullptr) { | ||
| 33 | + callBack(); | ||
| 34 | + } | ||
| 35 | + } | ||
| 36 | + OH_Image_Receiver_On_Callback callBack = nullptr; | ||
| 37 | +}; | ||
| 38 | +} // namespace Media | ||
| 39 | +} // namespace OHOS | ||
| 40 | + | ||
| @@ -214,6 +214,7 @@ if (use_clang_ios) { | |||
| 214 | ] | 214 | ] |
| 215 | 215 | ||
| 216 | sources = [ | 216 | sources = [ |
| 217 | + "${image_subsystem}/frameworks/innerkitsimpl/common/src/native_image.cpp", | ||
| 217 | "//foundation/multimedia/image_framework/frameworks/innerkitsimpl/codec/src/image_packer.cpp", | 218 | "//foundation/multimedia/image_framework/frameworks/innerkitsimpl/codec/src/image_packer.cpp", |
| 218 | "//foundation/multimedia/image_framework/frameworks/innerkitsimpl/codec/src/image_packer_ex.cpp", | 219 | "//foundation/multimedia/image_framework/frameworks/innerkitsimpl/codec/src/image_packer_ex.cpp", |
| 219 | "//foundation/multimedia/image_framework/frameworks/innerkitsimpl/codec/src/image_source.cpp", | 220 | "//foundation/multimedia/image_framework/frameworks/innerkitsimpl/codec/src/image_source.cpp", |
| @@ -0,0 +1,70 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (C) 2021 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 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | +namespace OHOS { | ||
| 27 | +namespace Media { | ||
| 28 | +struct NativeComponent { | ||
| 29 | + int32_t rowStride = 0; | ||
| 30 | + int32_t pixelStride = 0; | ||
| 31 | + std::vector<uint8_t> raw; | ||
| 32 | + uint8_t* virAddr; | ||
| 33 | + size_t size = 0; | ||
| 34 | +}; | ||
| 35 | + | ||
| 36 | +class IBufferProcessor { | ||
| 37 | +public: | ||
| 38 | + virtual ~IBufferProcessor() {}; | ||
| 39 | + virtual void BufferRelease(sptr<SurfaceBuffer>& buffer) = 0; | ||
| 40 | +}; | ||
| 41 | + | ||
| 42 | +class NativeImage { | ||
| 43 | +public: | ||
| 44 | + NativeImage(sptr<SurfaceBuffer> buffer, std::shared_ptr<IBufferProcessor> releaser); | ||
| 45 | + ~NativeImage() = default; | ||
| 46 | + int32_t GetSize(int32_t &width, int32_t &height); | ||
| 47 | + int32_t GetDataSize(uint64_t &size); | ||
| 48 | + int32_t GetFormat(int32_t &format); | ||
| 49 | + NativeComponent* GetComponent(int32_t type); | ||
| 50 | + int32_t CombineYUVComponents(); | ||
| 51 | + sptr<SurfaceBuffer> GetBuffer() | ||
| 52 | + { | ||
| 53 | + return buffer_; | ||
| 54 | + } | ||
| 55 | + void release(); | ||
| 56 | +private: | ||
| 57 | + NativeComponent* CreateComponent(int32_t type, size_t size, int32_t row, int32_t pixel, uint8_t* vir); | ||
| 58 | + NativeComponent* CreateCombineComponent(int32_t type); | ||
| 59 | + NativeComponent* GetCachedComponent(int32_t type); | ||
| 60 | + int32_t SplitYUV422SPComponent(); | ||
| 61 | + int32_t SplitSurfaceToComponent(); | ||
| 62 | + uint8_t* GetSurfaceBufferAddr(); | ||
| 63 | + sptr<SurfaceBuffer> buffer_; | ||
| 64 | + std::shared_ptr<IBufferProcessor> releaser_; | ||
| 65 | + std::map<int32_t, std::unique_ptr<NativeComponent>> components_; | ||
| 66 | +}; | ||
| 67 | +} // namespace Media | ||
| 68 | +} // namespace OHOS | ||
| 69 | + | ||
| 70 | + | ||
| @@ -31,6 +31,7 @@ | |||
| 31 | *BufferPackerStream*; | 31 | *BufferPackerStream*; |
| 32 | *BasicTransformer*; | 32 | *BasicTransformer*; |
| 33 | *IncrementalSourceStream*CreateSourceStream*; | 33 | *IncrementalSourceStream*CreateSourceStream*; |
| 34 | + *NativeImage*; | ||
| 34 | local: | 35 | local: |
| 35 | *; | 36 | *; |
| 36 | }; | 37 | }; |
| @@ -20,6 +20,7 @@ config("image_external_config") { | |||
| 20 | include_dirs = [ | 20 | include_dirs = [ |
| 21 | "include", | 21 | "include", |
| 22 | "//utils/system/safwk/native/include", | 22 | "//utils/system/safwk/native/include", |
| 23 | + "${image_subsystem}/frameworks/kits/js/common/ndk/include", | ||
| 23 | "//foundation/ability/ability_runtime/interfaces/inner_api/runtime/include/", | 24 | "//foundation/ability/ability_runtime/interfaces/inner_api/runtime/include/", |
| 24 | "//foundation/multimedia/image_framework/frameworks/innerkitsimpl/receiver/include", | 25 | "//foundation/multimedia/image_framework/frameworks/innerkitsimpl/receiver/include", |
| 25 | "//foundation/multimedia/image_framework/frameworks/innerkitsimpl/creator/include", | 26 | "//foundation/multimedia/image_framework/frameworks/innerkitsimpl/creator/include", |
| @@ -193,7 +194,9 @@ if (use_clang_ios) { | |||
| 193 | } | 194 | } |
| 194 | public_configs = [ ":image_external_config" ] | 195 | public_configs = [ ":image_external_config" ] |
| 195 | sources = [ | 196 | sources = [ |
| 197 | + "$image_subsystem/frameworks/kits/js/common/image_mdk_kits.cpp", | ||
| 196 | "$image_subsystem/frameworks/kits/js/common/image_pixel_map_napi_kits.cpp", | 198 | "$image_subsystem/frameworks/kits/js/common/image_pixel_map_napi_kits.cpp", |
| 199 | + "$image_subsystem/frameworks/kits/js/common/image_receiver_mdk_kits.cpp", | ||
| 197 | "//foundation/multimedia/image_framework/frameworks/kits/js/common/image_creator_napi.cpp", | 200 | "//foundation/multimedia/image_framework/frameworks/kits/js/common/image_creator_napi.cpp", |
| 198 | "//foundation/multimedia/image_framework/frameworks/kits/js/common/image_napi.cpp", | 201 | "//foundation/multimedia/image_framework/frameworks/kits/js/common/image_napi.cpp", |
| 199 | "//foundation/multimedia/image_framework/frameworks/kits/js/common/image_napi_utils.cpp", | 202 | "//foundation/multimedia/image_framework/frameworks/kits/js/common/image_napi_utils.cpp", |
| @@ -94,7 +94,7 @@ struct ImageCreatorAsyncContext { | |||
| 94 | uint32_t status; | 94 | uint32_t status; |
| 95 | sptr<SurfaceBuffer> surfaceBuffer; | 95 | sptr<SurfaceBuffer> surfaceBuffer; |
| 96 | std::shared_ptr<ImageSource> imageSource_; | 96 | std::shared_ptr<ImageSource> imageSource_; |
| 97 | - std::shared_ptr<ImageNapi> imageNapi_; | 97 | + std::shared_ptr<NativeImage> imageNapi_; |
| 98 | }; | 98 | }; |
| 99 | struct ImageCreatorInnerContext { | 99 | struct ImageCreatorInnerContext { |
| 100 | napi_status status; | 100 | napi_status status; |
| @@ -16,47 +16,24 @@ | |||
| 16 | 16 | ||
| 17 | 17 | ||
| 18 | 18 | ||
| 19 | -#include <cerrno> | 19 | +#include "native_image.h" |
| 20 | - | ||
| 21 | - | ||
| 22 | - | ||
| 23 | - | ||
| 24 | - | ||
| 25 | - | ||
| 26 | - | ||
| 27 | - | ||
| 28 | - | ||
| 29 | - | ||
| 30 | 20 | ||
| 31 | -#include "napi/native_node_api.h" | 21 | +#include "image_holder_manager.h" |
| 32 | - | ||
| 33 | - | ||
| 34 | 22 | ||
| 35 | namespace OHOS { | 23 | namespace OHOS { |
| 36 | namespace Media { | 24 | namespace Media { |
| 37 | struct ImageAsyncContext; | 25 | struct ImageAsyncContext; |
| 38 | -struct Component { | ||
| 39 | - int32_t rowStride = 0; | ||
| 40 | - int32_t pixelStride = 0; | ||
| 41 | - std::vector<uint8_t> raw; | ||
| 42 | -}; | ||
| 43 | - | ||
| 44 | class ImageNapi { | 26 | class ImageNapi { |
| 45 | public: | 27 | public: |
| 46 | ImageNapi(); | 28 | ImageNapi(); |
| 47 | ~ImageNapi(); | 29 | ~ImageNapi(); |
| 48 | static napi_value Init(napi_env env, napi_value exports); | 30 | static napi_value Init(napi_env env, napi_value exports); |
| 49 | - static std::shared_ptr<ImageNapi> GetImageSource(napi_env env, napi_value image); | 31 | + static napi_value Create(napi_env env); |
| 50 | - static napi_value Create(napi_env env, sptr<SurfaceBuffer> surfaceBuffer, | 32 | + static napi_value Create(napi_env env, std::shared_ptr<NativeImage> nativeImage); |
| 51 | - std::shared_ptr<ImageReceiver> imageReceiver); | 33 | + static std::shared_ptr<NativeImage> GetNativeImage(napi_env env, napi_value image); |
| 52 | - static napi_value Create(napi_env env, std::shared_ptr<ImageReceiver> imageReceiver); | 34 | + |
| 53 | - static napi_value CreateBufferToImage(napi_env env, sptr<SurfaceBuffer> surfaceBuffer, | 35 | + NativeImage* GetNative(); |
| 54 | - std::shared_ptr<ImageCreator> imageCreator); | ||
| 55 | void NativeRelease(); | 36 | void NativeRelease(); |
| 56 | - sptr<SurfaceBuffer> sSurfaceBuffer_; | ||
| 57 | - Component* CreateComponentData(ComponentType type, size_t size, int32_t rowStride, int32_t pixelStride); | ||
| 58 | - Component* GetComponentData(ComponentType type); | ||
| 59 | - uint32_t CombineComponentsIntoSurface(); | ||
| 60 | 37 | ||
| 61 | private: | 38 | private: |
| 62 | static napi_value Constructor(napi_env env, napi_callback_info info); | 39 | static napi_value Constructor(napi_env env, napi_callback_info info); |
| @@ -68,32 +45,10 @@ private: | |||
| 68 | static napi_value JsGetComponent(napi_env env, napi_callback_info info); | 45 | static napi_value JsGetComponent(napi_env env, napi_callback_info info); |
| 69 | static napi_value JsRelease(napi_env env, napi_callback_info info); | 46 | static napi_value JsRelease(napi_env env, napi_callback_info info); |
| 70 | 47 | ||
| 71 | - static napi_value BuildComponent(napi_env env, napi_callback_info info); | ||
| 72 | - static std::unique_ptr<ImageAsyncContext> UnwarpContext(napi_env env, napi_callback_info info); | ||
| 73 | - static void JsGetComponentCallBack(napi_env env, napi_status status, ImageAsyncContext* context); | ||
| 74 | - | ||
| 75 | - void release(); | ||
| 76 | - bool isRelease = false; | ||
| 77 | static thread_local napi_ref sConstructor_; | 48 | static thread_local napi_ref sConstructor_; |
| 78 | - static sptr<SurfaceBuffer> staticInstance_; | 49 | + static ImageHolderManager<NativeImage> sNativeImageHolder_; |
| 79 | - static std::shared_ptr<ImageReceiver> staticImageReceiverInstance_; | 50 | + std::shared_ptr<NativeImage> native_; |
| 80 | - static std::shared_ptr<ImageCreator> staticImageCreatorInstance_; | 51 | + bool isTestImage_; |
| 81 | - | ||
| 82 | - napi_env env_ = nullptr; | ||
| 83 | - std::shared_ptr<ImageReceiver> imageReceiver_; | ||
| 84 | - std::shared_ptr<ImageCreator> imageCreator_; | ||
| 85 | - std::shared_ptr<ImageNapi> nativeImage_; | ||
| 86 | - std::map<ComponentType, std::unique_ptr<Component>> componentData_; | ||
| 87 | -}; | ||
| 88 | - | ||
| 89 | -struct ImageAsyncContext { | ||
| 90 | - napi_env env = nullptr; | ||
| 91 | - napi_async_work work = nullptr; | ||
| 92 | - napi_deferred deferred = nullptr; | ||
| 93 | - napi_ref callbackRef = nullptr; | ||
| 94 | - ImageNapi *constructor_ = nullptr; | ||
| 95 | - uint32_t status; | ||
| 96 | - int32_t componentType; | ||
| 97 | }; | 52 | }; |
| 98 | } // namespace Media | 53 | } // namespace Media |
| 99 | } // namespace OHOS | 54 | } // namespace OHOS |
| @@ -35,8 +35,14 @@ namespace OHOS { | |||
| 35 | namespace Media { | 35 | namespace Media { |
| 36 | struct ImageReceiverCommonArgs; | 36 | struct ImageReceiverCommonArgs; |
| 37 | struct ImageReceiverAsyncContext; | 37 | struct ImageReceiverAsyncContext; |
| 38 | -using Context = ImageReceiverAsyncContext*; | 38 | +using Context = ImageReceiverAsyncContext* ; |
| 39 | using CompleteCallback = void (*)(napi_env env, napi_status status, Context context); | 39 | using CompleteCallback = void (*)(napi_env env, napi_status status, Context context); |
| 40 | +struct ImageReceiverCreateArgs { | ||
| 41 | + int32_t width; | ||
| 42 | + int32_t height; | ||
| 43 | + int32_t format; | ||
| 44 | + int32_t capicity; | ||
| 45 | +}; | ||
| 40 | class ImageReceiverNapi { | 46 | class ImageReceiverNapi { |
| 41 | public: | 47 | public: |
| 42 | ImageReceiverNapi(); | 48 | ImageReceiverNapi(); |
| @@ -45,6 +51,8 @@ public: | |||
| 45 | static void DoCallBack(std::shared_ptr<ImageReceiverAsyncContext> context, | 51 | static void DoCallBack(std::shared_ptr<ImageReceiverAsyncContext> context, |
| 46 | std::string name, | 52 | std::string name, |
| 47 | CompleteCallback callBack); | 53 | CompleteCallback callBack); |
| 54 | + ImageReceiver* GetNative(); | ||
| 55 | + static napi_value CreateImageReceiverJsObject(napi_env env, struct ImageReceiverCreateArgs args); | ||
| 48 | void NativeRelease(); | 56 | void NativeRelease(); |
| 49 | 57 | ||
| 50 | bool isCallBackTest = false; | 58 | bool isCallBackTest = false; |
| @@ -23,3 +23,28 @@ ohos_ndk_headers("image_header") { | |||
| 23 | dest_dir = "$ndk_headers_out_dir/multimedia/image_framework" | 23 | dest_dir = "$ndk_headers_out_dir/multimedia/image_framework" |
| 24 | sources = [ "./include/image_pixel_map_napi.h" ] | 24 | sources = [ "./include/image_pixel_map_napi.h" ] |
| 25 | } | 25 | } |
| 26 | + | ||
| 27 | +ohos_ndk_library("libimage_ndk") { | ||
| 28 | + ndk_description_file = "./libimage_ndk.ndk.json" | ||
| 29 | + min_compact_version = "1" | ||
| 30 | + output_name = "image_ndk" | ||
| 31 | +} | ||
| 32 | + | ||
| 33 | +ohos_ndk_headers("image_ndk_header") { | ||
| 34 | + dest_dir = "$ndk_headers_out_dir/multimedia/image_framework" | ||
| 35 | + sources = [ | ||
| 36 | + "./include/image_mdk.h", | ||
| 37 | + "./include/image_mdk_common.h", | ||
| 38 | + ] | ||
| 39 | +} | ||
| 40 | + | ||
| 41 | +ohos_ndk_library("libimage_receiver_ndk") { | ||
| 42 | + ndk_description_file = "./libimage_receiver_ndk.ndk.json" | ||
| 43 | + min_compact_version = "1" | ||
| 44 | + output_name = "image_receiver_ndk" | ||
| 45 | +} | ||
| 46 | + | ||
| 47 | +ohos_ndk_headers("image_receiver_ndk_header") { | ||
| 48 | + dest_dir = "$ndk_headers_out_dir/multimedia/image_framework" | ||
| 49 | + sources = [ "./include/image_receiver_mdk.h" ] | ||
| 50 | +} | ||
| @@ -0,0 +1,209 @@ | |||
| 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 | +/** | ||
| 17 | + * @addtogroup image | ||
| 18 | + * @{ | ||
| 19 | + * | ||
| 20 | + * @brief Provides access image functions. | ||
| 21 | + * | ||
| 22 | + * @Syscap SystemCapability.Multimedia.Image | ||
| 23 | + * @since 10 | ||
| 24 | + * @version 2.0 | ||
| 25 | + */ | ||
| 26 | + | ||
| 27 | +/** | ||
| 28 | + * @file image_mdk.h | ||
| 29 | + * | ||
| 30 | + * @brief Declares function to access image clip rect, size, format and component data. | ||
| 31 | + * | ||
| 32 | + * @since 10 | ||
| 33 | + * @version 2.0 | ||
| 34 | + */ | ||
| 35 | + | ||
| 36 | + | ||
| 37 | + | ||
| 38 | + | ||
| 39 | + | ||
| 40 | + | ||
| 41 | +namespace OHOS { | ||
| 42 | +namespace Media { | ||
| 43 | + | ||
| 44 | +extern "C" { | ||
| 45 | + | ||
| 46 | + | ||
| 47 | +struct ImageNative_; | ||
| 48 | + | ||
| 49 | +/** | ||
| 50 | + * @brief Defines native image object for image functions. | ||
| 51 | + * | ||
| 52 | + * @since 10 | ||
| 53 | + * @version 2.0 | ||
| 54 | + */ | ||
| 55 | +typedef struct ImageNative_ ImageNative; | ||
| 56 | + | ||
| 57 | +/** | ||
| 58 | + * @brief Enumerates for image formats. | ||
| 59 | + * | ||
| 60 | + * @since 10 | ||
| 61 | + * @version 2.0 | ||
| 62 | + */ | ||
| 63 | +enum { | ||
| 64 | + /** YCBCR422 semi-planar format.*/ | ||
| 65 | + OHOS_IMAGE_FORMAT_YCBCR_422_SP = 1000, | ||
| 66 | + /** JPEG encoding format.*/ | ||
| 67 | + OHOS_IMAGE_FORMAT_JPEG = 2000 | ||
| 68 | +}; | ||
| 69 | + | ||
| 70 | +/** | ||
| 71 | + * @brief Enumerates for the component type of image. | ||
| 72 | + * | ||
| 73 | + * @since 10 | ||
| 74 | + * @version 2.0 | ||
| 75 | + */ | ||
| 76 | +enum { | ||
| 77 | + /** Luma info.*/ | ||
| 78 | + OHOS_IMAGE_COMPONENT_FORMAT_YUV_Y = 1, | ||
| 79 | + /** Chrominance info.*/ | ||
| 80 | + OHOS_IMAGE_COMPONENT_FORMAT_YUV_U = 2, | ||
| 81 | + /** Chroma info.*/ | ||
| 82 | + OHOS_IMAGE_COMPONENT_FORMAT_YUV_V = 3, | ||
| 83 | + /** Jpeg type.*/ | ||
| 84 | + OHOS_IMAGE_COMPONENT_FORMAT_JPEG = 4, | ||
| 85 | +}; | ||
| 86 | + | ||
| 87 | +/** | ||
| 88 | + * @brief Defines image rect infomations. | ||
| 89 | + * | ||
| 90 | + * @since 10 | ||
| 91 | + * @version 2.0 | ||
| 92 | + */ | ||
| 93 | +struct OhosImageRect { | ||
| 94 | + /** Rect x coordinate */ | ||
| 95 | + int32_t x; | ||
| 96 | + /** Rect y coordinate */ | ||
| 97 | + int32_t y; | ||
| 98 | + /** Rect width size */ | ||
| 99 | + int32_t width; | ||
| 100 | + /** Rect height size */ | ||
| 101 | + int32_t height; | ||
| 102 | +}; | ||
| 103 | + | ||
| 104 | +/** | ||
| 105 | + * @brief Defines image component infomations. | ||
| 106 | + * | ||
| 107 | + * @since 10 | ||
| 108 | + * @version 2.0 | ||
| 109 | + */ | ||
| 110 | +struct OhosImageComponent { | ||
| 111 | + /** Component pixel data address */ | ||
| 112 | + uint8_t* byteBuffer; | ||
| 113 | + /** Component pixel data size in memory */ | ||
| 114 | + size_t size; | ||
| 115 | + /** Component type of pixel data */ | ||
| 116 | + int32_t componentType; | ||
| 117 | + /** Component row stride of pixel data */ | ||
| 118 | + int32_t rowStride; | ||
| 119 | + /** Component pixel size of pixel data */ | ||
| 120 | + int32_t pixelStride; | ||
| 121 | +}; | ||
| 122 | + | ||
| 123 | +/** | ||
| 124 | + * @brief Unwrap native {@link ImageNative} object from input JavaScript Native API <b>Image</b> object. | ||
| 125 | + * | ||
| 126 | + * @param env Indicates the pointer to the JNI environment. | ||
| 127 | + * @param source Indicates the JavaScript Native API <b>Image</b> object. | ||
| 128 | + * @return Returns {@link ImageNative} pointer if the operation is successful; returns nullptr if the | ||
| 129 | + * operation fails. | ||
| 130 | + * @see ImageNative, OH_Image_Release | ||
| 131 | + * @since 10 | ||
| 132 | + * @version 2.0 | ||
| 133 | + */ | ||
| 134 | +ImageNative* OH_Image_InitImageNative(napi_env env, napi_value source); | ||
| 135 | + | ||
| 136 | +/** | ||
| 137 | + * @brief Get {@link OhosImageRect} infomation of native {@link ImageNative} object. | ||
| 138 | + * | ||
| 139 | + * @param native Indicates the pointer to {@link ImageNative} native object. | ||
| 140 | + * @param rect Indicates the pointer of {@link OhosImageRect} object as result. | ||
| 141 | + * @return Returns {@link OHOS_IMAGE_RESULT_SUCCESS} if the operation is successful; | ||
| 142 | + * returns other result codes if the operation fails. | ||
| 143 | + * @see ImageNative, OhosImageRect | ||
| 144 | + * @since 10 | ||
| 145 | + * @version 2.0 | ||
| 146 | + */ | ||
| 147 | +int32_t OH_Image_ClipRect(const ImageNative* native, struct OhosImageRect* rect); | ||
| 148 | + | ||
| 149 | +/** | ||
| 150 | + * @brief Get {@link OhosImageSize} infomation of native {@link ImageNative} object. | ||
| 151 | + * | ||
| 152 | + * @param native Indicates the pointer to {@link ImageNative} native object. | ||
| 153 | + * @param size Indicates the pointer of {@link OhosImageSize} object as result. | ||
| 154 | + * @return Returns {@link OHOS_IMAGE_RESULT_SUCCESS} if the operation is successful; | ||
| 155 | + * returns other result codes if the operation fails. | ||
| 156 | + * @see ImageNative, OhosImageSize | ||
| 157 | + * @since 10 | ||
| 158 | + * @version 2.0 | ||
| 159 | + */ | ||
| 160 | +int32_t OH_Image_Size(const ImageNative* native, struct OhosImageSize* size); | ||
| 161 | + | ||
| 162 | +/** | ||
| 163 | + * @brief Get image format of native {@link ImageNative} object. | ||
| 164 | + * | ||
| 165 | + * @param native Indicates the pointer to {@link ImageNative} native object. | ||
| 166 | + * @param format Indicates the pointer of format object as result. | ||
| 167 | + * @return Returns {@link OHOS_IMAGE_RESULT_SUCCESS} if the operation is successful; | ||
| 168 | + * returns other result codes if the operation fails. | ||
| 169 | + * @see ImageNative | ||
| 170 | + * @since 10 | ||
| 171 | + * @version 2.0 | ||
| 172 | + */ | ||
| 173 | +int32_t OH_Image_Format(const ImageNative* native, int32_t* format); | ||
| 174 | + | ||
| 175 | +/** | ||
| 176 | + * @brief Get {@link OhosImageComponent} from native {@link ImageNative} object. | ||
| 177 | + * | ||
| 178 | + * @param native Indicates the pointer to {@link ImageNative} native object. | ||
| 179 | + * @param componentType Indicates the component type of component wanted. | ||
| 180 | + * @param componentNative Indicates the pointer of result {@link OhosImageComponent} object. | ||
| 181 | + * @return Returns {@link OHOS_IMAGE_RESULT_SUCCESS} if the operation is successful; | ||
| 182 | + * returns other result codes if the operation fails. | ||
| 183 | + * @see ImageNative, OhosImageComponent | ||
| 184 | + * @since 10 | ||
| 185 | + * @version 2.0 | ||
| 186 | + */ | ||
| 187 | +int32_t OH_Image_GetComponent(const ImageNative* native, | ||
| 188 | + int32_t componentType, struct OhosImageComponent* componentNative); | ||
| 189 | + | ||
| 190 | +/** | ||
| 191 | + * @brief Release {@link ImageNative} native object. | ||
| 192 | + * Note: This function could not release JavaScript Native API <b>Image</b> object but | ||
| 193 | + * the {@link ImageNative} native object unwrap by {@link OH_Image_InitImageNative}. | ||
| 194 | + * | ||
| 195 | + * @param native Indicates the pointer to {@link ImageNative} native object. | ||
| 196 | + * @return Returns {@link OHOS_IMAGE_RESULT_SUCCESS} if the operation is successful; | ||
| 197 | + * returns other result codes if the operation fails. | ||
| 198 | + * @see ImageNative, OH_Image_InitImageNative | ||
| 199 | + * @since 10 | ||
| 200 | + * @version 2.0 | ||
| 201 | + */ | ||
| 202 | +int32_t OH_Image_Release(ImageNative* native); | ||
| 203 | + | ||
| 204 | +}; | ||
| 205 | + | ||
| 206 | +/** @} */ | ||
| 207 | +} // namespace Media | ||
| 208 | +} // namespace OHOS | ||
| 209 | + | ||
| @@ -0,0 +1,76 @@ | |||
| 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 | +/** | ||
| 17 | + * @addtogroup image | ||
| 18 | + * @{ | ||
| 19 | + * | ||
| 20 | + * @brief Provides access image functions. | ||
| 21 | + * | ||
| 22 | + * @Syscap SystemCapability.Multimedia.Image | ||
| 23 | + * @since 10 | ||
| 24 | + * @version 2.0 | ||
| 25 | + */ | ||
| 26 | + | ||
| 27 | +/** | ||
| 28 | + * @file image_mdk_common.h | ||
| 29 | + * | ||
| 30 | + * @brief Declares common enumerates and structure for image. | ||
| 31 | + * | ||
| 32 | + * @since 10 | ||
| 33 | + * @version 2.0 | ||
| 34 | + */ | ||
| 35 | + | ||
| 36 | + | ||
| 37 | + | ||
| 38 | +namespace OHOS { | ||
| 39 | +namespace Media { | ||
| 40 | + | ||
| 41 | +extern "C" { | ||
| 42 | + | ||
| 43 | + | ||
| 44 | +/** | ||
| 45 | + * @brief Enumerates the result codes that may be returned by a function. | ||
| 46 | + * | ||
| 47 | + * @since 8 | ||
| 48 | + * @version 1.0 | ||
| 49 | + */ | ||
| 50 | +enum { | ||
| 51 | + /** Success result */ | ||
| 52 | + OHOS_IMAGE_RESULT_SUCCESS = 0, | ||
| 53 | + /** Invalid parameters */ | ||
| 54 | + OHOS_IMAGE_RESULT_BAD_PARAMETER = -1, | ||
| 55 | +}; | ||
| 56 | + | ||
| 57 | +/** | ||
| 58 | + * @brief Defines image size. | ||
| 59 | + * | ||
| 60 | + * @since 10 | ||
| 61 | + * @version 2.0 | ||
| 62 | + */ | ||
| 63 | +struct OhosImageSize { | ||
| 64 | + /** Image width, in pixels. */ | ||
| 65 | + int32_t width; | ||
| 66 | + /** Image height, in pixels. */ | ||
| 67 | + int32_t height; | ||
| 68 | +}; | ||
| 69 | + | ||
| 70 | + | ||
| 71 | +}; | ||
| 72 | + | ||
| 73 | +/** @} */ | ||
| 74 | +} // namespace Media | ||
| 75 | +} // namespace OHOS | ||
| 76 | + | ||
| @@ -0,0 +1,225 @@ | |||
| 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 | +/** | ||
| 17 | + * @addtogroup image | ||
| 18 | + * @{ | ||
| 19 | + * | ||
| 20 | + * @brief Provides functions to access the native buffer of image, receiving ready buffer from native. | ||
| 21 | + * | ||
| 22 | + * @Syscap SystemCapability.Multimedia.Image | ||
| 23 | + * @since 10 | ||
| 24 | + * @version 2.0 | ||
| 25 | + */ | ||
| 26 | + | ||
| 27 | +/** | ||
| 28 | + * @file image_receiver_mdk.h | ||
| 29 | + * | ||
| 30 | + * @brief Declares functions for you to access native image buffer in native layer. | ||
| 31 | + * | ||
| 32 | + * @since 10 | ||
| 33 | + * @version 2.0 | ||
| 34 | + */ | ||
| 35 | + | ||
| 36 | + | ||
| 37 | + | ||
| 38 | + | ||
| 39 | + | ||
| 40 | + | ||
| 41 | + | ||
| 42 | + | ||
| 43 | +namespace OHOS { | ||
| 44 | +namespace Media { | ||
| 45 | + | ||
| 46 | +extern "C" { | ||
| 47 | + | ||
| 48 | + | ||
| 49 | +struct ImageReceiverNative_; | ||
| 50 | +/** | ||
| 51 | + * @brief Defines native image receiver object for native receiving functions. | ||
| 52 | + * | ||
| 53 | + * @since 10 | ||
| 54 | + * @version 2.0 | ||
| 55 | + */ | ||
| 56 | +typedef struct ImageReceiverNative_ ImageReceiverNative; | ||
| 57 | + | ||
| 58 | +/** | ||
| 59 | + * @brief Defines a type of callback on native image ready. | ||
| 60 | + * | ||
| 61 | + * @since 10 | ||
| 62 | + * @version 2.0 | ||
| 63 | + */ | ||
| 64 | +typedef void (*OH_Image_Receiver_On_Callback)(); | ||
| 65 | + | ||
| 66 | +/** | ||
| 67 | + * @brief Defines image receiver create infomations. | ||
| 68 | + * | ||
| 69 | + * @since 10 | ||
| 70 | + * @version 2.0 | ||
| 71 | + */ | ||
| 72 | +struct OhosImageReceiverInfo { | ||
| 73 | + /** Default image width size on receive. */ | ||
| 74 | + int32_t width; | ||
| 75 | + /** Default image height size on receive. */ | ||
| 76 | + int32_t height; | ||
| 77 | + /** Create image format throught receiver. */ | ||
| 78 | + int32_t format; | ||
| 79 | + /** Max capicity of images cache. */ | ||
| 80 | + int32_t capicity; | ||
| 81 | +}; | ||
| 82 | + | ||
| 83 | +/** | ||
| 84 | + * @brief Obtains JavaScript Native API <b>ImageReceiver</b> object by a given infomations {@link | ||
| 85 | + * OhosImageReceiverInfo} structure. | ||
| 86 | + * | ||
| 87 | + * @param env Indicates the pointer to the JNI environment. | ||
| 88 | + * @param info Indicates infomations of creating a image receiver. For details, | ||
| 89 | + * see {@link OhosImageReceiverInfo}. | ||
| 90 | + * @param res Indicates the pointer to JavaScript Native API <b>ImageReceiver</b> object. | ||
| 91 | + * @return Returns {@link OHOS_IMAGE_RESULT_SUCCESS} if the operation is successful; | ||
| 92 | + * returns other result codes if the operation fails. | ||
| 93 | + * @see OhosImageReceiverInfo | ||
| 94 | + * @since 10 | ||
| 95 | + * @version 2.0 | ||
| 96 | + */ | ||
| 97 | +int32_t OH_Image_Receiver_CreateImageReceiver(napi_env env, struct OhosImageReceiverInfo info, napi_value* res); | ||
| 98 | + | ||
| 99 | +/** | ||
| 100 | + * @brief Unwrap native {@link ImageReceiverNative} value from input JavaScript Native API | ||
| 101 | + * <b>ImageReceiver</b> object. | ||
| 102 | + * | ||
| 103 | + * @param env Indicates the pointer to the JNI environment. | ||
| 104 | + * @param source Indicates JavaScript Native API <b>ImageReceiver</b> object. | ||
| 105 | + * @return Returns {@link ImageReceiverNative} pointer if the operation is successful; | ||
| 106 | + * returns nullptr result if the operation fails. | ||
| 107 | + * @see ImageReceiverNative, OH_Image_Receiver_Release | ||
| 108 | + * @since 10 | ||
| 109 | + * @version 2.0 | ||
| 110 | + */ | ||
| 111 | +ImageReceiverNative* OH_Image_Receiver_InitImageReceiverNative(napi_env env, napi_value source); | ||
| 112 | + | ||
| 113 | +/** | ||
| 114 | + * @brief Get receiver id from native {@link ImageReceiverNative} value. | ||
| 115 | + * | ||
| 116 | + * @param native Indicates the pointer to native {@link ImageReceiverNative} value. | ||
| 117 | + * @param id Indicates the pointer to a char buffer for taking the string id. | ||
| 118 | + * @param len Indicates the <b>id</b> char buffer size. | ||
| 119 | + * @return Returns {@link OHOS_IMAGE_RESULT_SUCCESS} if the operation is successful; | ||
| 120 | + * returns other result codes if the operation fails. | ||
| 121 | + * @see ImageReceiverNative | ||
| 122 | + * @since 10 | ||
| 123 | + * @version 2.0 | ||
| 124 | + */ | ||
| 125 | +int32_t OH_Image_Receiver_GetReceivingSurfaceId(const ImageReceiverNative* native, char* id, size_t len); | ||
| 126 | + | ||
| 127 | +/** | ||
| 128 | + * @brief Read the latest image from native {@link ImageReceiverNative} value at least one image ready. | ||
| 129 | + * | ||
| 130 | + * @param native Indicates the pointer to native {@link ImageReceiverNative} value. | ||
| 131 | + * @param image Indicates the pointer to JavaScript Native API <b>Image</b> object by reading. | ||
| 132 | + * @return Returns {@link OHOS_IMAGE_RESULT_SUCCESS} if the operation is successful; | ||
| 133 | + * returns other result codes if the operation fails. | ||
| 134 | + * @see ImageReceiverNative | ||
| 135 | + * @since 10 | ||
| 136 | + * @version 2.0 | ||
| 137 | + */ | ||
| 138 | +int32_t OH_Image_Receiver_ReadLatestImage(const ImageReceiverNative* native, napi_value* image); | ||
| 139 | + | ||
| 140 | +/** | ||
| 141 | + * @brief Read the next image from native {@link ImageReceiverNative} value at least one image ready. | ||
| 142 | + * | ||
| 143 | + * @param native Indicates the pointer to native {@link ImageReceiverNative} value. | ||
| 144 | + * @param image Indicates the pointer to JavaScript Native API <b>Image</b> object by reading. | ||
| 145 | + * @return Returns {@link OHOS_IMAGE_RESULT_SUCCESS} if the operation is successful; | ||
| 146 | + * returns other result codes if the operation fails. | ||
| 147 | + * @see ImageReceiverNative | ||
| 148 | + * @since 10 | ||
| 149 | + * @version 2.0 | ||
| 150 | + */ | ||
| 151 | +int32_t OH_Image_Receiver_ReadNextImage(const ImageReceiverNative* native, napi_value* image); | ||
| 152 | + | ||
| 153 | +/** | ||
| 154 | + * @brief Register an {@link OH_Image_Receiver_On_Callback} event callback. The callback function will be | ||
| 155 | + * called when image ready everytime. | ||
| 156 | + * | ||
| 157 | + * @param native Indicates the pointer to native {@link ImageReceiverNative} value. | ||
| 158 | + * @param callback Indicates the callback function to {@link OH_Image_Receiver_On_Callback} event. | ||
| 159 | + * @return Returns {@link OHOS_IMAGE_RESULT_SUCCESS} if the operation is successful; | ||
| 160 | + * returns other result codes if the operation fails. | ||
| 161 | + * @see ImageReceiverNative | ||
| 162 | + * @since 10 | ||
| 163 | + * @version 2.0 | ||
| 164 | + */ | ||
| 165 | +int32_t OH_Image_Receiver_On(const ImageReceiverNative* native, OH_Image_Receiver_On_Callback callback); | ||
| 166 | + | ||
| 167 | +/** | ||
| 168 | + * @brief Get recevier size from native {@link ImageReceiverNative} value. | ||
| 169 | + * | ||
| 170 | + * @param native Indicates the pointer to native {@link ImageReceiverNative} value. | ||
| 171 | + * @param size Indicates the pointer to {@link OhosImageSize} value as result. | ||
| 172 | + * @return Returns {@link OHOS_IMAGE_RESULT_SUCCESS} if the operation is successful; | ||
| 173 | + * returns other result codes if the operation fails. | ||
| 174 | + * @see ImageReceiverNative, OH_Image_Receiver_On_Callback | ||
| 175 | + * @since 10 | ||
| 176 | + * @version 2.0 | ||
| 177 | + */ | ||
| 178 | +int32_t OH_Image_Receiver_GetSize(const ImageReceiverNative* native, struct OhosImageSize* size); | ||
| 179 | + | ||
| 180 | +/** | ||
| 181 | + * @brief Get recevier capacity from native {@link ImageReceiverNative} value. | ||
| 182 | + * | ||
| 183 | + * @param native Indicates the pointer to native {@link ImageReceiverNative} value. | ||
| 184 | + * @param capacity Indicates the pointer to capacity value as result. | ||
| 185 | + * @return Returns {@link OHOS_IMAGE_RESULT_SUCCESS} if the operation is successful; | ||
| 186 | + * returns other result codes if the operation fails. | ||
| 187 | + * @see ImageReceiverNative, OhosImageSize | ||
| 188 | + * @since 10 | ||
| 189 | + * @version 2.0 | ||
| 190 | + */ | ||
| 191 | +int32_t OH_Image_Receiver_GetCapacity(const ImageReceiverNative* native, int32_t* capacity); | ||
| 192 | + | ||
| 193 | +/** | ||
| 194 | + * @brief Get recevier format from native {@link ImageReceiverNative} value. | ||
| 195 | + * | ||
| 196 | + * @param native Indicates the pointer to native {@link ImageReceiverNative} value. | ||
| 197 | + * @param format Indicates the pointer to format value as result. | ||
| 198 | + * @return Returns {@link OHOS_IMAGE_RESULT_SUCCESS} if the operation is successful; | ||
| 199 | + * returns other result codes if the operation fails. | ||
| 200 | + * @see ImageReceiverNative | ||
| 201 | + * @since 10 | ||
| 202 | + * @version 2.0 | ||
| 203 | + */ | ||
| 204 | +int32_t OH_Image_Receiver_GetFormat(const ImageReceiverNative* native, int32_t* format); | ||
| 205 | + | ||
| 206 | +/** | ||
| 207 | + * @brief Release native {@link ImageReceiverNative} object. | ||
| 208 | + * Note: This function could not release JavaScript Native API <b>ImageReceiver</b> object but the | ||
| 209 | + * native {@link ImageReceiverNative} object unwrap by <b>OH_Image_Receiver_InitImageReceiverNative</b>. | ||
| 210 | + * | ||
| 211 | + * @param native Indicates the pointer to native {@link ImageReceiverNative} value. | ||
| 212 | + * @return Returns {@link OHOS_IMAGE_RESULT_SUCCESS} if the operation is successful; | ||
| 213 | + * returns other result codes if the operation fails. | ||
| 214 | + * @see ImageReceiverNative | ||
| 215 | + * @since 10 | ||
| 216 | + * @version 2.0 | ||
| 217 | + */ | ||
| 218 | +int32_t OH_Image_Receiver_Release(ImageReceiverNative* native); | ||
| 219 | + | ||
| 220 | +}; | ||
| 221 | + | ||
| 222 | +/** @} */ | ||
| 223 | +} // namespace Media | ||
| 224 | +} // namespace OHOS | ||
| 225 | + | ||
| @@ -0,0 +1,21 @@ | |||
| 1 | +[ | ||
| 2 | + { | ||
| 3 | + "first_introduced": "1", | ||
| 4 | + "name": "OH_Image_InitImageNative" | ||
| 5 | + }, | ||
| 6 | + { | ||
| 7 | + "name": "OH_Image_ClipRect" | ||
| 8 | + }, | ||
| 9 | + { | ||
| 10 | + "name": "OH_Image_Size" | ||
| 11 | + }, | ||
| 12 | + { | ||
| 13 | + "name": "OH_Image_Format" | ||
| 14 | + }, | ||
| 15 | + { | ||
| 16 | + "name": "OH_Image_GetComponent" | ||
| 17 | + }, | ||
| 18 | + { | ||
| 19 | + "name": "OH_Image_Release" | ||
| 20 | + } | ||
| 21 | +] | ||
| @@ -0,0 +1,33 @@ | |||
| 1 | +[ | ||
| 2 | + { | ||
| 3 | + "first_introduced": "1", | ||
| 4 | + "name": "OH_Image_Receiver_CreateImageReceiver" | ||
| 5 | + }, | ||
| 6 | + { | ||
| 7 | + "name": "OH_Image_Receiver_InitImageReceiverNative" | ||
| 8 | + }, | ||
| 9 | + { | ||
| 10 | + "name": "OH_Image_Receiver_GetReceivingSurfaceId" | ||
| 11 | + }, | ||
| 12 | + { | ||
| 13 | + "name": "OH_Image_Receiver_ReadLatestImage" | ||
| 14 | + }, | ||
| 15 | + { | ||
| 16 | + "name": "OH_Image_Receiver_ReadNextImage" | ||
| 17 | + }, | ||
| 18 | + { | ||
| 19 | + "name": "OH_Image_Receiver_On" | ||
| 20 | + }, | ||
| 21 | + { | ||
| 22 | + "name": "OH_Image_Receiver_GetSize" | ||
| 23 | + }, | ||
| 24 | + { | ||
| 25 | + "name": "OH_Image_Receiver_GetCapacity" | ||
| 26 | + }, | ||
| 27 | + { | ||
| 28 | + "name": "OH_Image_Receiver_GetFormat" | ||
| 29 | + }, | ||
| 30 | + { | ||
| 31 | + "name": "OH_Image_Receiver_Release" | ||
| 32 | + } | ||
| 33 | +] | ||