• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "hdi_init.h"
17 #include <hdf_base.h>
18 #include "media_log.h"
19 #include "media_errors.h"
20 #include "display_type.h"
21 #include "scope_guard.h"
22 #include "hdi_codec_util.h"
23 #include "hdf_remote_service.h"
24 #include "codec_internal.h"
25 #include "servmgr_hdi.h"
26 
27 namespace {
28     constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "HdiInit"};
29     using namespace OHOS::Media;
30     const std::unordered_map<int32_t, int32_t> AVC_PROFILE_MAP = {
31         {OMX_VIDEO_AVCProfileBaseline, AVC_PROFILE_BASELINE},
32         {OMX_VIDEO_AVCProfileMain, AVC_PROFILE_MAIN},
33         {OMX_VIDEO_AVCProfileHigh, AVC_PROFILE_HIGH},
34         {OMX_VIDEO_AVCProfileExtended, AVC_PROFILE_EXTENDED},
35     };
36 
37     const std::unordered_map<int32_t, int32_t> HEVC_PROFILE_MAP = {
38         {CODEC_HEVC_PROFILE_MAIN, HEVC_PROFILE_MAIN},
39         {CODEC_HEVC_PROFILE_MAIN10, HEVC_PROFILE_MAIN_10},
40         {CODEC_HEVC_PROFILE_MAIN_STILL, HEVC_PROFILE_MAIN_STILL},
41         {CODEC_HEVC_PROFILE_MAIN10_HDR10, HEVC_PROFILE_MAIN_10_HDR10},
42     };
43 
44     const std::unordered_map<int32_t, int32_t> AVC_LEVEL_MAP = {
45         {OMX_VIDEO_AVCLevel1, AVC_LEVEL_1},
46         {OMX_VIDEO_AVCLevel1b, AVC_LEVEL_1b},
47         {OMX_VIDEO_AVCLevel11, AVC_LEVEL_11},
48         {OMX_VIDEO_AVCLevel12, AVC_LEVEL_12},
49         {OMX_VIDEO_AVCLevel13, AVC_LEVEL_13},
50         {OMX_VIDEO_AVCLevel2, AVC_LEVEL_2},
51         {OMX_VIDEO_AVCLevel21, AVC_LEVEL_21},
52         {OMX_VIDEO_AVCLevel22, AVC_LEVEL_22},
53         {OMX_VIDEO_AVCLevel3, AVC_LEVEL_3},
54         {OMX_VIDEO_AVCLevel31, AVC_LEVEL_31},
55         {OMX_VIDEO_AVCLevel32, AVC_LEVEL_32},
56         {OMX_VIDEO_AVCLevel4, AVC_LEVEL_4},
57         {OMX_VIDEO_AVCLevel41, AVC_LEVEL_41},
58         {OMX_VIDEO_AVCLevel42, AVC_LEVEL_42},
59         {OMX_VIDEO_AVCLevel5, AVC_LEVEL_5},
60         {OMX_VIDEO_AVCLevel51, AVC_LEVEL_51},
61     };
62 
63     const std::unordered_map<int32_t, int32_t> HEVC_LEVEL_MAP = {
64         {CODEC_HEVC_MAIN_TIER_LEVEL1, HEVC_LEVEL_1},
65         {CODEC_HEVC_MAIN_TIER_LEVEL2, HEVC_LEVEL_2},
66         {CODEC_HEVC_MAIN_TIER_LEVEL21, HEVC_LEVEL_21},
67         {CODEC_HEVC_MAIN_TIER_LEVEL3, HEVC_LEVEL_3},
68         {CODEC_HEVC_MAIN_TIER_LEVEL31, HEVC_LEVEL_31},
69         {CODEC_HEVC_MAIN_TIER_LEVEL4, HEVC_LEVEL_4},
70         {CODEC_HEVC_MAIN_TIER_LEVEL41, HEVC_LEVEL_41},
71         {CODEC_HEVC_MAIN_TIER_LEVEL5, HEVC_LEVEL_5},
72         {CODEC_HEVC_MAIN_TIER_LEVEL51, HEVC_LEVEL_51},
73         {CODEC_HEVC_MAIN_TIER_LEVEL52, HEVC_LEVEL_52},
74         {CODEC_HEVC_MAIN_TIER_LEVEL6, HEVC_LEVEL_6},
75         {CODEC_HEVC_MAIN_TIER_LEVEL61, HEVC_LEVEL_61},
76         {CODEC_HEVC_MAIN_TIER_LEVEL62, HEVC_LEVEL_62},
77     };
78     constexpr int32_t MAX_COMPONENT_NUM = 1024;
79 }
80 
81 namespace OHOS {
82 namespace Media {
83 const std::unordered_map<int32_t, HdiInit::GetProfileLevelsFunc> HdiInit::PROFILE_LEVEL_FUNC_MAP = {
84     {MEDIA_ROLETYPE_VIDEO_AVC, HdiInit::GetH264ProfileLevels},
85     {MEDIA_ROLETYPE_VIDEO_HEVC, HdiInit::GetH265ProfileLevels},
86 };
87 
GetInstance()88 HdiInit &HdiInit::GetInstance()
89 {
90     static HdiInit omx;
91     return omx;
92 }
93 
HdiInit()94 HdiInit::HdiInit()
95 {
96     MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
97     CodecComponentManagerInit();
98 }
99 
~HdiInit()100 HdiInit::~HdiInit()
101 {
102     MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
103     CodecComponentManagerRelease();
104 }
105 
HdiCodecOnRemoteDied(HdfDeathRecipient * deathRecipient,HdfRemoteService * remote)106 static void HdiCodecOnRemoteDied(HdfDeathRecipient *deathRecipient, HdfRemoteService *remote)
107 {
108     (void)deathRecipient;
109     (void)remote;
110     HdiInit::GetInstance().CodecComponentManagerReset();
111 }
112 
CodecComponentManagerInit()113 void HdiInit::CodecComponentManagerInit()
114 {
115     MEDIA_LOGD("CodecComponentManagerInit In");
116 
117     mgr_ = GetCodecComponentManager();
118     CHECK_AND_RETURN_LOG(mgr_ != nullptr, "GetCodecComponentManager failed");
119 
120     HDIServiceManager *serviceMgr = HDIServiceManagerGet();
121     CHECK_AND_RETURN_LOG(serviceMgr != nullptr, "HDIServiceManagerGet failed");
122 
123     HdfRemoteService *remoteOmx = serviceMgr->GetService(serviceMgr, CODEC_HDI_OMX_SERVICE_NAME);
124     HDIServiceManagerRelease(serviceMgr);
125     CHECK_AND_RETURN_LOG(remoteOmx != nullptr, "HDIServiceManagerGet failed");
126 
127     static HdfDeathRecipient recipient = {
128         .OnRemoteDied = HdiCodecOnRemoteDied,
129     };
130 
131     HdfRemoteServiceAddDeathRecipient(remoteOmx, &recipient);
132 
133     MEDIA_LOGD("CodecComponentManagerInit End");
134 }
135 
CodecComponentManagerReset()136 void HdiInit::CodecComponentManagerReset()
137 {
138     MEDIA_LOGD("CodecComponentManagerReset In");
139 
140     std::lock_guard<std::mutex> lock(mutex_);
141     CodecComponentManagerRelease();
142     mgr_ = nullptr;
143     handleMap_.clear();
144 
145     MEDIA_LOGD("CodecComponentManagerReset End");
146 }
147 
GetCodecType(CodecType hdiType)148 int32_t HdiInit::GetCodecType(CodecType hdiType)
149 {
150     switch (hdiType) {
151         case VIDEO_DECODER:
152             return AVCODEC_TYPE_VIDEO_DECODER;
153         case VIDEO_ENCODER:
154             return AVCODEC_TYPE_VIDEO_ENCODER;
155         case AUDIO_DECODER:
156             return AVCODEC_TYPE_AUDIO_DECODER;
157         case AUDIO_ENCODER:
158             return AVCODEC_TYPE_AUDIO_ENCODER;
159         default:
160             MEDIA_LOGW("Unknow codecType");
161             break;
162     }
163     return AVCODEC_TYPE_NONE;
164 }
165 
GetCodecMime(AvCodecRole & role)166 std::string HdiInit::GetCodecMime(AvCodecRole &role)
167 {
168     switch (role) {
169         case MEDIA_ROLETYPE_VIDEO_AVC:
170             return "video/avc";
171         case MEDIA_ROLETYPE_VIDEO_HEVC:
172             return "video/hevc";
173         default:
174             MEDIA_LOGW("Unknow codecRole %{public}d", (int32_t)role);
175             break;
176     }
177     return "invalid";
178 }
179 
GetBitrateMode(CodecVideoPortCap & port)180 std::vector<int32_t> HdiInit::GetBitrateMode(CodecVideoPortCap &port)
181 {
182     int32_t index = 0;
183     std::vector<int32_t> bitrate;
184     while (index < BIT_RATE_MODE_NUM && port.bitRatemode[index] != BIT_RATE_MODE_INVALID) {
185         switch (port.bitRatemode[index]) {
186             case BIT_RATE_MODE_VBR:
187                 bitrate.push_back(VBR);
188                 break;
189             case BIT_RATE_MODE_CBR:
190                 bitrate.push_back(CBR);
191                 break;
192             case BIT_RATE_MODE_CQ:
193                 bitrate.push_back(CQ);
194                 break;
195             default:
196                 MEDIA_LOGW("Unknow bitrate mode %{public}d", port.bitRatemode[index]);
197         }
198         index++;
199     }
200     return bitrate;
201 }
202 
GetMeasuredFrameRate(CodecVideoPortCap & port)203 std::map<ImgSize, Range> HdiInit::GetMeasuredFrameRate(CodecVideoPortCap &port)
204 {
205     int32_t index = 0;
206     std::map<ImgSize, Range> rateMap;
207     const int32_t measureStep = 4;
208     // measuredFrameRate is 0 width 1 height 2 minRate 3 maxRate. So the step is 4.
209     while (index < MEASURED_FRAME_RATE_NUM && port.measuredFrameRate[index] > 0) {
210         ImgSize imageSize(port.measuredFrameRate[index], port.measuredFrameRate[index + 1]);
211         Range range(port.measuredFrameRate[index + 2], port.measuredFrameRate[index + 3]);
212         rateMap[imageSize] = range;
213         index += measureStep;
214     }
215     return rateMap;
216 }
217 
GetCodecFormats(CodecVideoPortCap & port)218 std::vector<int32_t> HdiInit::GetCodecFormats(CodecVideoPortCap &port)
219 {
220     int32_t index = 0;
221     std::vector<int32_t> formats;
222     while (index < PIX_FORMAT_NUM && port.supportPixFmts[index] > 0) {
223         switch (port.supportPixFmts[index]) {
224             case PIXEL_FMT_YCBCR_420_SP:
225                 formats.push_back(NV12);
226                 break;
227             case PIXEL_FMT_YCRCB_420_SP:
228                 formats.push_back(NV21);
229                 break;
230             case PIXEL_FMT_YCBCR_420_P:
231                 formats.push_back(YUVI420);
232                 break;
233             case PIXEL_FMT_RGBA_8888:
234                 formats.push_back(RGBA);
235                 break;
236             default:
237                 MEDIA_LOGW("Unknow Format %{public}d", port.supportPixFmts[index]);
238         }
239         index++;
240     }
241 
242     return formats;
243 }
244 
GetH264ProfileLevels(CodecCompCapability & hdiCap)245 std::map<int32_t, std::vector<int32_t>> HdiInit::GetH264ProfileLevels(CodecCompCapability &hdiCap)
246 {
247     std::map<int32_t, std::vector<int32_t>> profileLevelsMap;
248     int32_t index = 0;
249     while (index < PROFILE_NUM && hdiCap.supportProfiles[index] > 0) {
250         if (AVC_PROFILE_MAP.find(hdiCap.supportProfiles[index]) == AVC_PROFILE_MAP.end()) {
251             MEDIA_LOGW("Unknow AVC profile %{public}d", hdiCap.supportProfiles[index]);
252             break;
253         }
254         int32_t profile = AVC_PROFILE_MAP.at(hdiCap.supportProfiles[index]);
255         if (profileLevelsMap.find(profile) == profileLevelsMap.end()) {
256             profileLevelsMap[profile] = std::vector<int32_t>();
257         }
258         index++;
259         if (AVC_LEVEL_MAP.find(hdiCap.supportProfiles[index]) == AVC_LEVEL_MAP.end()) {
260             MEDIA_LOGW("Unknow AVC level %{public}d", hdiCap.supportProfiles[index]);
261             break;
262         }
263         profileLevelsMap[profile].push_back(AVC_LEVEL_MAP.at(hdiCap.supportProfiles[index]));
264         index++;
265     }
266 
267     return profileLevelsMap;
268 }
269 
GetH265ProfileLevels(CodecCompCapability & hdiCap)270 std::map<int32_t, std::vector<int32_t>> HdiInit::GetH265ProfileLevels(CodecCompCapability &hdiCap)
271 {
272     std::map<int32_t, std::vector<int32_t>> profileLevelsMap;
273     int32_t index = 0;
274     std::vector<int32_t> formats;
275     while (index < PROFILE_NUM && hdiCap.supportProfiles[index] > 0) {
276         if (HEVC_PROFILE_MAP.find(hdiCap.supportProfiles[index]) == HEVC_PROFILE_MAP.end()) {
277             MEDIA_LOGW("Unknow HEVC profile %{public}d", hdiCap.supportProfiles[index]);
278             break;
279         }
280         int32_t profile = HEVC_PROFILE_MAP.at(hdiCap.supportProfiles[index]);
281         if (profileLevelsMap.find(profile) == profileLevelsMap.end()) {
282             profileLevelsMap[profile] = std::vector<int32_t>();
283         }
284         index++;
285         if (HEVC_LEVEL_MAP.find(hdiCap.supportProfiles[index]) == HEVC_LEVEL_MAP.end()) {
286             MEDIA_LOGW("Unknow HEVC level %{public}d", hdiCap.supportProfiles[index]);
287             break;
288         }
289         profileLevelsMap[profile].push_back(HEVC_LEVEL_MAP.at(hdiCap.supportProfiles[index]));
290         index++;
291     }
292 
293     return profileLevelsMap;
294 }
295 
GetCodecProfileLevels(CodecCompCapability & hdiCap)296 std::map<int32_t, std::vector<int32_t>> HdiInit::GetCodecProfileLevels(CodecCompCapability &hdiCap)
297 {
298     if (PROFILE_LEVEL_FUNC_MAP.find(hdiCap.role) == PROFILE_LEVEL_FUNC_MAP.end()) {
299         MEDIA_LOGW("Unknow role %{public}d", hdiCap.role);
300         return std::map<int32_t, std::vector<int32_t>>();
301     }
302     return PROFILE_LEVEL_FUNC_MAP.at(hdiCap.role)(hdiCap);
303 }
304 
AddHdiCap(CodecCompCapability & hdiCap)305 void HdiInit::AddHdiCap(CodecCompCapability &hdiCap)
306 {
307     MEDIA_LOGI("Add codec name %{public}s", hdiCap.compName);
308     CapabilityData codecCap;
309     codecCap.codecName = hdiCap.compName;
310     codecCap.codecType = GetCodecType(hdiCap.type);
311     codecCap.mimeType = GetCodecMime(hdiCap.role);
312     codecCap.isVendor = !hdiCap.isSoftwareCodec;
313     codecCap.alignment = {hdiCap.port.video.whAlignment.widthAlignment, hdiCap.port.video.whAlignment.heightAlignment};
314     codecCap.bitrateMode = GetBitrateMode(hdiCap.port.video);
315     codecCap.width = {hdiCap.port.video.minSize.width, hdiCap.port.video.maxSize.width};
316     codecCap.height = {hdiCap.port.video.minSize.height, hdiCap.port.video.maxSize.height};
317     codecCap.bitrate = {hdiCap.bitRate.min, hdiCap.bitRate.max};
318     codecCap.frameRate = {hdiCap.port.video.frameRate.min, hdiCap.port.video.frameRate.max};
319     codecCap.format = GetCodecFormats(hdiCap.port.video);
320     codecCap.blockPerFrame = {hdiCap.port.video.blockCount.min, hdiCap.port.video.blockCount.max};
321     codecCap.blockPerSecond = {hdiCap.port.video.blocksPerSecond.min, hdiCap.port.video.blocksPerSecond.max};
322     codecCap.blockSize = {hdiCap.port.video.blockSize.width, hdiCap.port.video.blockSize.height};
323     codecCap.measuredFrameRate = GetMeasuredFrameRate(hdiCap.port.video);
324     codecCap.profileLevelsMap = GetCodecProfileLevels(hdiCap);
325     capabilitys_.push_back(codecCap);
326 }
327 
InitCaps()328 void HdiInit::InitCaps()
329 {
330     if (!capabilitys_.empty()) {
331         return;
332     }
333     auto len = mgr_->GetComponentNum();
334     if (len >= MAX_COMPONENT_NUM || len <= 0) {
335         MEDIA_LOGW("Component num is %{public}d", len);
336         return;
337     }
338     CodecCompCapability *hdiCaps = new CodecCompCapability[len];
339     CHECK_AND_RETURN_LOG(hdiCaps != nullptr, "New CodecCompCapability fail");
340     ON_SCOPE_EXIT(0) { delete[] hdiCaps; };
341     auto ret = mgr_->GetComponentCapabilityList(hdiCaps, len);
342     CHECK_AND_RETURN_LOG(ret == HDF_SUCCESS, "GetComponentCapabilityList fail");
343     for (auto i = 0; i < len; ++i) {
344         AddHdiCap(hdiCaps[i]);
345     }
346 }
347 
GetCapabilitys()348 std::vector<CapabilityData> HdiInit::GetCapabilitys()
349 {
350     std::lock_guard<std::mutex> lock(mutex_);
351     CHECK_AND_RETURN_RET_LOG(mgr_ != nullptr, capabilitys_, "mgr is nullptr");
352     InitCaps();
353     return capabilitys_;
354 }
355 
GetHandle(CodecComponentType ** component,uint32_t & id,std::string name,void * appData,CodecCallbackType * callbacks)356 int32_t HdiInit::GetHandle(CodecComponentType **component, uint32_t &id, std::string name,
357     void *appData, CodecCallbackType *callbacks)
358 {
359     std::lock_guard<std::mutex> lock(mutex_);
360     if (mgr_ == nullptr) {
361         CodecComponentManagerInit();
362         CHECK_AND_RETURN_RET_LOG(mgr_ != nullptr, HDF_FAILURE, "mgr is nullptr");
363     }
364 
365     CHECK_AND_RETURN_RET_LOG(component != nullptr, HDF_FAILURE, "component is nullptr");
366     int32_t ret = mgr_->CreateComponent(component, &id, const_cast<char *>(name.c_str()),
367         reinterpret_cast<int64_t>(appData), callbacks);
368     if (ret == HDF_SUCCESS) {
369         handleMap_[*component] = id;
370     }
371 
372     return ret;
373 }
374 
FreeHandle(CodecComponentType * component,uint32_t id)375 int32_t HdiInit::FreeHandle(CodecComponentType *component, uint32_t id)
376 {
377     CHECK_AND_RETURN_RET_LOG(mgr_ != nullptr, HDF_FAILURE, "mgr_ is nullptr");
378 
379     std::lock_guard<std::mutex> lock(mutex_);
380     auto iter = handleMap_.find(component);
381     CHECK_AND_RETURN_RET_LOG(iter != handleMap_.end(), HDF_SUCCESS, "The handle has been released!");
382     CHECK_AND_RETURN_RET_LOG(iter->second == id, HDF_FAILURE, "Handle and id do not match!");
383 
384     int32_t ret =  mgr_->DestroyComponent(id);
385     if (ret == HDF_SUCCESS) {
386         handleMap_.erase(iter);
387     }
388 
389     return ret;
390 }
391 }  // namespace Media
392 }  // namespace OHOS
393