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