1/*
2 * Copyright (c) 2023-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 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 "histreamer_query_tool.h"
17
18#include <dlfcn.h>
19#include <malloc.h>
20
21#include "distributed_hardware_log.h"
22
23namespace OHOS {
24namespace DistributedHardware {
25IMPLEMENT_SINGLE_INSTANCE(HiStreamerQueryTool);
26using QueryAudioEncoderFunc = int32_t (*)(char*);
27using QueryAudioDecoderFunc = int32_t (*)(char*);
28using QueryVideoEncoderFunc = int32_t (*)(char*);
29using QueryVideoDecoderFunc = int32_t (*)(char*);
30
31QueryAudioEncoderFunc queryAudioEncoderFunc = nullptr;
32QueryAudioDecoderFunc queryAudioDecoderFunc = nullptr;
33QueryVideoEncoderFunc queryVideoEncoderFunc = nullptr;
34QueryVideoDecoderFunc queryVideoDecoderFunc = nullptr;
35
36const std::string QueryAudioEncoderFuncName = "QueryAudioEncoderAbilityStr";
37const std::string QueryAudioDecoderFuncName = "QueryAudioDecoderAbilityStr";
38const std::string QueryVideoEncoderFuncName = "QueryVideoEncoderAbilityStr";
39const std::string QueryVideoDecoderFuncName = "QueryVideoDecoderAbilityStr";
40
41const uint32_t MAX_MESSAGES_LEN = 1 * 1024 * 1024;
42
43const std::string LOAD_SO = "libhistreamer_ability_querier.z.so";
44
45void HiStreamerQueryTool::Init()
46{
47    if (isInit) {
48        return;
49    }
50    DHLOGI("Start Init HiStreamer Query SO");
51    void *pHandler = dlopen(LOAD_SO.c_str(), RTLD_LAZY | RTLD_NODELETE);
52    if (pHandler == nullptr) {
53        DHLOGE("libhistreamer_ability_querier.z.so handler load failed, failed reason : %{public}s", dlerror());
54        return;
55    }
56
57    queryAudioEncoderFunc = (QueryAudioEncoderFunc)dlsym(pHandler,
58        QueryAudioEncoderFuncName.c_str());
59    if (queryAudioEncoderFunc == nullptr) {
60        DHLOGE("get QueryAudioEncoderAbilityStr is null, failed reason : %{public}s", dlerror());
61        dlclose(pHandler);
62        pHandler = nullptr;
63        return;
64    }
65
66    queryAudioDecoderFunc = (QueryAudioDecoderFunc)dlsym(pHandler,
67        QueryAudioDecoderFuncName.c_str());
68    if (queryAudioDecoderFunc == nullptr) {
69        DHLOGE("get QueryAudioDecoderAbilityStr is null, failed reason : %{public}s", dlerror());
70        dlclose(pHandler);
71        pHandler = nullptr;
72        return;
73    }
74
75    queryVideoEncoderFunc = (QueryVideoEncoderFunc)dlsym(pHandler,
76        QueryVideoEncoderFuncName.c_str());
77    if (queryVideoEncoderFunc == nullptr) {
78        DHLOGE("get QueryVideoEncoderAbilityStr is null, failed reason : %{public}s", dlerror());
79        dlclose(pHandler);
80        pHandler = nullptr;
81        return;
82    }
83
84    queryVideoDecoderFunc = (QueryVideoDecoderFunc)dlsym(pHandler,
85        QueryVideoDecoderFuncName.c_str());
86    if (queryVideoDecoderFunc == nullptr) {
87        DHLOGE("get QueryVideoDecoderAbilityStr is null, failed reason : %{public}s", dlerror());
88        dlclose(pHandler);
89        pHandler = nullptr;
90        return;
91    }
92
93    DHLOGI("Init Query HiStreamer Tool Success");
94    isInit = true;
95}
96
97std::string HiStreamerQueryTool::QueryHiStreamerPluginInfo(HISTREAM_PLUGIN_TYPE type)
98{
99    Init();
100    if (!isInit || queryAudioEncoderFunc == nullptr || queryAudioDecoderFunc == nullptr ||
101        queryVideoEncoderFunc == nullptr || queryVideoDecoderFunc == nullptr) {
102        DHLOGE("Query HiStreamer Tool Init failed");
103        return "";
104    }
105
106    int32_t len = 0;
107    char* res = reinterpret_cast<char *>(malloc(MAX_MESSAGES_LEN));
108    if (res == nullptr) {
109        DHLOGE("Malloc memory failed");
110        return "";
111    }
112    switch (type) {
113        case HISTREAM_PLUGIN_TYPE::AUDIO_ENCODER: {
114            len = queryAudioEncoderFunc(res);
115            break;
116        }
117        case HISTREAM_PLUGIN_TYPE::AUDIO_DECODER: {
118            len = queryAudioDecoderFunc(res);
119            break;
120        }
121        case HISTREAM_PLUGIN_TYPE::VIDEO_ENCODER: {
122            len = queryVideoEncoderFunc(res);
123            break;
124        }
125        case HISTREAM_PLUGIN_TYPE::VIDEO_DECODER: {
126            len = queryVideoDecoderFunc(res);
127            break;
128        }
129        default:
130            break;
131    }
132
133    std::string result(res, len);
134    free(res);
135    res = nullptr;
136    return result;
137}
138}
139}