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 law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <dlfcn.h>
17 #include <poll.h>
18 #include <securec.h>
19 #include <unistd.h>
20 #include "codec_jpeg_core.h"
21 #include "codec_log_wrapper.h"
22 #include "hdf_base.h"
23
24 #define MAX_WAIT_MS 10
25
26 namespace OHOS {
27 namespace HDI {
28 namespace Codec {
29 namespace Image {
30 int CodecJpegCore::fence_ = -1;
31 OHOS::sptr<V1_0::ICodecImageCallback> CodecJpegCore::callback_ = nullptr;
OnEvent(int32_t error)32 int32_t CodecJpegCore::OnEvent(int32_t error)
33 {
34 CODEC_LOGI("response decode callback, ret =[%{public}d]", error);
35 CHECK_AND_RETURN_RET_LOG(callback_ != nullptr, HDF_ERR_INVALID_PARAM, "callback_ is null");
36
37 if (fence_ >= 0 && error == HDF_SUCCESS) {
38 auto ret = SyncWait(fence_);
39 if (ret != EOK) {
40 CODEC_LOGE("SyncWait ret err [%{public}d]", ret);
41 }
42 }
43 if (fence_ >= 0) {
44 close(fence_);
45 fence_ = -1;
46 }
47 (void)callback_->OnImageEvent(error);
48 callback_ = nullptr;
49 return HDF_SUCCESS;
50 }
51
~CodecJpegCore()52 CodecJpegCore::~CodecJpegCore()
53 {
54 if (libHandle_ != nullptr) {
55 dlclose(libHandle_);
56 }
57 callback_ = nullptr;
58 }
59
CodecJpegCore()60 CodecJpegCore::CodecJpegCore()
61 {
62 vdiCallback_ = {&CodecJpegCore::OnEvent};
63 }
64
AddVendorLib()65 void CodecJpegCore::AddVendorLib()
66 {
67 CODEC_LOGI("start load dependency library!");
68 std::string libName = HDF_LIBRARY_FULL_PATH(CODEC_JPEG_VDI_NAME);
69 char pathBuf[PATH_MAX] = {'\0'};
70 if (realpath(libName.c_str(), pathBuf) == nullptr) {
71 CODEC_LOGE("realpath failed! path = [%{public}s]", pathBuf);
72 return;
73 }
74 libHandle_ = dlopen(pathBuf, RTLD_LAZY);
75 if (libHandle_ == nullptr) {
76 CODEC_LOGE("Failed to dlopen %{public}s.", libName.c_str());
77 return;
78 }
79
80 getCodecJpegHwi_= reinterpret_cast<GetCodecJpegHwi>(dlsym(libHandle_, "GetCodecJpegHwi"));
81 if (getCodecJpegHwi_ == NULL) {
82 CODEC_LOGE("Failed to dlsym GetCodecJpegHwi");
83 return;
84 }
85
86 JpegHwi_ = getCodecJpegHwi_();
87 if (JpegHwi_ == nullptr) {
88 CODEC_LOGE("load dependency library error!");
89 return;
90 }
91 CODEC_LOGI("load dependency library success!");
92 }
93
Init()94 int32_t CodecJpegCore::Init()
95 {
96 if (JpegHwi_ == nullptr) {
97 AddVendorLib();
98 }
99 CHECK_AND_RETURN_RET_LOG(JpegHwi_ != nullptr, HDF_FAILURE, "JpegHwi_ is null");
100 return (JpegHwi_->JpegInit)();
101 }
102
DeInit()103 int32_t CodecJpegCore::DeInit()
104 {
105 CHECK_AND_RETURN_RET_LOG(JpegHwi_ != nullptr, HDF_FAILURE, "JpegHwi_ is null");
106 return (JpegHwi_->JpegDeInit)();
107 }
108
AllocateInBuffer(BufferHandle ** buffer,uint32_t size)109 int32_t CodecJpegCore::AllocateInBuffer(BufferHandle **buffer, uint32_t size)
110 {
111 CHECK_AND_RETURN_RET_LOG(JpegHwi_ != nullptr, HDF_FAILURE, "JpegHwi_ is null");
112 return (JpegHwi_->AllocateInBuffer)(buffer, size);
113 }
114
FreeInBuffer(BufferHandle * buffer)115 int32_t CodecJpegCore::FreeInBuffer(BufferHandle *buffer)
116 {
117 CHECK_AND_RETURN_RET_LOG(JpegHwi_ != nullptr, HDF_FAILURE, "JpegHwi_ is null");
118 return (JpegHwi_->FreeInBuffer)(buffer);
119 }
120
DoDecode(BufferHandle * buffer,BufferHandle * outBuffer,const V1_0::CodecJpegDecInfo * decInfo,const OHOS::sptr<V1_0::ICodecImageCallback> callbacks,int fd)121 int32_t CodecJpegCore::DoDecode(BufferHandle *buffer, BufferHandle *outBuffer,
122 const V1_0::CodecJpegDecInfo *decInfo, const OHOS::sptr<V1_0::ICodecImageCallback> callbacks, int fd)
123 {
124 CHECK_AND_RETURN_RET_LOG(JpegHwi_ != nullptr, HDF_FAILURE, "JpegHwi_ is null");
125 CodecJpegDecInfo *vdiDecInfo = reinterpret_cast<CodecJpegDecInfo *>(const_cast<V1_0::CodecJpegDecInfo *>(decInfo));
126
127 int32_t ret = (JpegHwi_->DoJpegDecode)(buffer, outBuffer, vdiDecInfo, &vdiCallback_);
128 if (ret == HDF_SUCCESS) {
129 callback_ = callbacks;
130 fence_ = fd;
131 }
132 return ret;
133 }
134
SyncWait(int fd)135 int32_t CodecJpegCore::SyncWait(int fd)
136 {
137 int retCode = -EPERM;
138 struct pollfd pollfds = {0};
139 pollfds.fd = fd;
140 pollfds.events = POLLIN;
141
142 do {
143 retCode = poll(&pollfds, 1, MAX_WAIT_MS);
144 } while (retCode == -EPERM && (errno == EINTR || errno == EAGAIN));
145
146 if (retCode == 0) {
147 CODEC_LOGE("fenceFd poll wait timeout !");
148 retCode = -EPERM;
149 errno = ETIME;
150 } else if (retCode > 0) {
151 if (static_cast<uint32_t>(pollfds.revents) & (POLLERR | POLLNVAL)) {
152 retCode = -EPERM;
153 errno = EINVAL;
154 }
155 }
156 return retCode < 0 ? -errno : EOK;
157 }
158 } // Image
159 } // Codec
160 } // HDI
161 } // OHOS
162