• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 #include "codec_heif_encode_service.h"
16 #include "codec_log_wrapper.h"
17 #include "hdf_base.h"
18 #include "hdf_remote_service.h"
19 #include "v1_0/display_composer_type.h"
20 #include "v1_0/imapper.h"
21 #include "v1_1/imetadata.h"
22 #include <dlfcn.h>
23 #include <unistd.h>
24 #include <mutex>
25 
26 namespace OHOS {
27 namespace HDI {
28 namespace Codec {
29 namespace Image {
30 namespace V2_0 {
31 using GetCodecHeifHwi = ICodecHeifHwi*(*)();
32 
33 std::mutex g_mapperMtx;
34 std::mutex g_metaMtx;
35 sptr<OHOS::HDI::Display::Buffer::V1_0::IMapper> g_mapperService;
36 sptr<OHOS::HDI::Display::Buffer::V1_1::IMetadata> g_metaService;
37 
GetMapperService()38 sptr<OHOS::HDI::Display::Buffer::V1_0::IMapper> GetMapperService()
39 {
40     std::lock_guard<std::mutex> lk(g_mapperMtx);
41     if (g_mapperService) {
42         return g_mapperService;
43     }
44     g_mapperService = OHOS::HDI::Display::Buffer::V1_0::IMapper::Get(true);
45     if (g_mapperService) {
46         CODEC_LOGI("get IMapper succ");
47         return g_mapperService;
48     }
49     CODEC_LOGE("get IMapper failed");
50     return nullptr;
51 }
52 
GetMetaService()53 sptr<OHOS::HDI::Display::Buffer::V1_1::IMetadata> GetMetaService()
54 {
55     std::lock_guard<std::mutex> lk(g_metaMtx);
56     if (g_metaService) {
57         return g_metaService;
58     }
59     g_metaService = OHOS::HDI::Display::Buffer::V1_1::IMetadata::Get(true);
60     if (g_metaService) {
61         CODEC_LOGI("get IMetadata succ");
62         return g_metaService;
63     }
64     CODEC_LOGE("get IMetadata failed");
65     return nullptr;
66 }
67 
BufferDestructor(BufferHandle * handle)68 void BufferDestructor(BufferHandle* handle)
69 {
70     if (handle == nullptr) {
71         return;
72     }
73     sptr<OHOS::HDI::Display::Buffer::V1_0::IMapper> mapper = GetMapperService();
74     if (mapper == nullptr) {
75         return;
76     }
77     sptr<NativeBuffer> buffer = new NativeBuffer();
78     buffer->SetBufferHandle(handle, true);
79     mapper->FreeMem(buffer);
80 }
81 
ReWrapNativeBuffer(sptr<NativeBuffer> & buffer)82 bool ReWrapNativeBuffer(sptr<NativeBuffer>& buffer)
83 {
84     if (buffer == nullptr) {
85         return true;
86     }
87     BufferHandle* handle = buffer->Move();
88     if (handle == nullptr) {
89         return true;
90     }
91     buffer->SetBufferHandle(handle, true, BufferDestructor);
92     sptr<OHOS::HDI::Display::Buffer::V1_1::IMetadata> meta = GetMetaService();
93     if (meta == nullptr) {
94         return false;
95     }
96     int32_t ret = meta->RegisterBuffer(buffer);
97     if (ret != Display::Composer::V1_0::DISPLAY_SUCCESS &&
98         ret != Display::Composer::V1_0::DISPLAY_NOT_SUPPORT) {
99         CODEC_LOGE("RegisterBuffer failed, ret = %{public}d", ret);
100         return false;
101     }
102     return true;
103 }
104 
CodecHeifEncodeService()105 CodecHeifEncodeService::CodecHeifEncodeService()
106 {
107     isIPCMode_ = (HdfRemoteGetCallingPid() == getpid() ? false : true);
108 }
109 
~CodecHeifEncodeService()110 CodecHeifEncodeService::~CodecHeifEncodeService()
111 {
112     heifHwi_ = nullptr;
113     libHeif_ = nullptr;
114 }
115 
LoadVendorLib()116 bool CodecHeifEncodeService::LoadVendorLib()
117 {
118     std::lock_guard<std::mutex> lk(mutex_);
119     if (heifHwi_) {
120         return true;
121     }
122     if (libHeif_ == nullptr) {
123         void *handle = dlopen(CODEC_HEIF_VDI_LIB_NAME, RTLD_LAZY);
124         if (handle == nullptr) {
125             CODEC_LOGE("failed to load vendor lib");
126             return false;
127         }
128         libHeif_ = std::shared_ptr<void>(handle, dlclose);
129     }
130     auto func = reinterpret_cast<GetCodecHeifHwi>(dlsym(libHeif_.get(), "GetCodecHeifHwi"));
131     if (func == nullptr) {
132         CODEC_LOGE("failed to load symbol from vendor lib");
133         return false;
134     }
135     heifHwi_ = func();
136     if (heifHwi_ == nullptr) {
137         CODEC_LOGE("failed to create heif hardware encoder");
138         return false;
139     }
140     return true;
141 }
142 
ReWrapNativeBufferInImageItem(const std::vector<ImageItem> & inputImgs)143 bool CodecHeifEncodeService::ReWrapNativeBufferInImageItem(const std::vector<ImageItem>& inputImgs)
144 {
145     if (!isIPCMode_) {
146         return true;
147     }
148 
149     for (const auto &image : inputImgs) {
150         if (!ReWrapNativeBuffer(const_cast<ImageItem &>(image).pixelBuffer)) {
151             return false;
152         }
153     }
154 
155     return true;
156 }
157 
DoHeifEncode(const std::vector<ImageItem> & inputImgs,const std::vector<MetaItem> & inputMetas,const std::vector<ItemRef> & refs,const SharedBuffer & output,uint32_t & filledLen)158 int32_t CodecHeifEncodeService::DoHeifEncode(const std::vector<ImageItem>& inputImgs,
159                                              const std::vector<MetaItem>& inputMetas,
160                                              const std::vector<ItemRef>& refs,
161                                              const SharedBuffer& output, uint32_t& filledLen)
162 {
163     if (!LoadVendorLib()) {
164         return HDF_FAILURE;
165     }
166 
167     if (!ReWrapNativeBufferInImageItem(inputImgs)) {
168         return HDF_FAILURE;
169     }
170 
171     SharedBuffer outputToReturn = output;
172     int32_t ret = (heifHwi_->DoHeifEncode)(inputImgs, inputMetas, refs, outputToReturn);
173     filledLen = outputToReturn.filledLen;
174     auto releaseRes = [](int fd) {
175         if (fd > 0) {
176             close(fd);
177         }
178     };
179     for (auto one : inputImgs) {
180         releaseRes(one.sharedProperties.fd);
181     }
182     for (auto one : inputMetas) {
183         releaseRes(one.data.fd);
184     }
185     releaseRes(output.fd);
186     return ret;
187 }
188 } // V2_0
189 } // Image
190 } // Codec
191 } // HDI
192 } // OHOS