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 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 #define HST_LOG_TAG "ReferenceParserManager"
17
18 #include <unistd.h>
19 #include <dlfcn.h>
20 #include "common/log.h"
21 #include "reference_parser_manager.h"
22
23 namespace {
24 const std::string REFERENCE_LIB_PATH = "libav_codec_reference_parser.z.so";
25 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_DEMUXER, "HiStreamer"};
26 }
27
28 namespace OHOS {
29 namespace Media {
30 namespace Plugins {
31 void *ReferenceParserManager::handler_ = nullptr;
32 ReferenceParserManager::CreateFunc ReferenceParserManager::createFunc_ = nullptr;
33 ReferenceParserManager::DestroyFunc ReferenceParserManager::destroyFunc_ = nullptr;
34 std::mutex ReferenceParserManager::mtx_;
35
~ReferenceParserManager()36 ReferenceParserManager::~ReferenceParserManager()
37 {
38 if (referenceParser_) {
39 destroyFunc_(referenceParser_);
40 referenceParser_ = nullptr;
41 }
42 }
43
Init()44 bool ReferenceParserManager::Init()
45 {
46 std::lock_guard<std::mutex> lock(mtx_);
47 if (!handler_) {
48 if (!CheckSymbol(LoadPluginFile(REFERENCE_LIB_PATH))) {
49 MEDIA_LOG_E("Load reference parser failed");
50 return false;
51 }
52 }
53 return true;
54 }
55
Create(CodecType codecType,std::vector<uint32_t> & IFramePos)56 std::shared_ptr<ReferenceParserManager> ReferenceParserManager::Create(CodecType codecType,
57 std::vector<uint32_t> &IFramePos)
58 {
59 std::shared_ptr<ReferenceParserManager> loader = std::make_shared<ReferenceParserManager>();
60 if (!loader->Init()) {
61 return nullptr;
62 }
63 loader->referenceParser_ = loader->createFunc_(codecType, IFramePos);
64 if (!loader->referenceParser_) {
65 MEDIA_LOG_E("CreateFunc_ fail");
66 return nullptr;
67 }
68 return loader;
69 }
70
ParserNalUnits(uint8_t * nalData,int32_t nalDataSize,uint32_t frameId,int64_t dts)71 Status ReferenceParserManager::ParserNalUnits(uint8_t *nalData, int32_t nalDataSize, uint32_t frameId, int64_t dts)
72 {
73 FALSE_RETURN_V_MSG_E(referenceParser_ != nullptr, Status::ERROR_NULL_POINTER, "Reference parser is nullptr");
74 return referenceParser_->ParserNalUnits(nalData, nalDataSize, frameId, dts);
75 }
76
ParserExtraData(uint8_t * extraData,int32_t extraDataSize)77 Status ReferenceParserManager::ParserExtraData(uint8_t *extraData, int32_t extraDataSize)
78 {
79 FALSE_RETURN_V_MSG_E(referenceParser_ != nullptr, Status::ERROR_NULL_POINTER, "Reference parser is nullptr");
80 return referenceParser_->ParserExtraData(extraData, extraDataSize);
81 }
82
ParserSdtpData(uint8_t * sdtpData,int32_t sdtpDataSize)83 Status ReferenceParserManager::ParserSdtpData(uint8_t *sdtpData, int32_t sdtpDataSize)
84 {
85 FALSE_RETURN_V_MSG_E(referenceParser_ != nullptr, Status::ERROR_NULL_POINTER, "Reference parser is nullptr");
86 return referenceParser_->ParserSdtpData(sdtpData, sdtpDataSize);
87 }
88
GetFrameLayerInfo(uint32_t frameId,FrameLayerInfo & frameLayerInfo)89 Status ReferenceParserManager::GetFrameLayerInfo(uint32_t frameId, FrameLayerInfo &frameLayerInfo)
90 {
91 FALSE_RETURN_V_MSG_E(referenceParser_ != nullptr, Status::ERROR_NULL_POINTER, "Reference parser is nullptr");
92 return referenceParser_->GetFrameLayerInfo(frameId, frameLayerInfo);
93 }
94
GetFrameLayerInfo(int64_t dts,FrameLayerInfo & frameLayerInfo)95 Status ReferenceParserManager::GetFrameLayerInfo(int64_t dts, FrameLayerInfo &frameLayerInfo)
96 {
97 FALSE_RETURN_V_MSG_E(referenceParser_ != nullptr, Status::ERROR_NULL_POINTER, "Reference parser is nullptr");
98 return referenceParser_->GetFrameLayerInfo(dts, frameLayerInfo);
99 }
100
GetGopLayerInfo(uint32_t gopId,GopLayerInfo & gopLayerInfo)101 Status ReferenceParserManager::GetGopLayerInfo(uint32_t gopId, GopLayerInfo &gopLayerInfo)
102 {
103 FALSE_RETURN_V_MSG_E(referenceParser_ != nullptr, Status::ERROR_NULL_POINTER, "Reference parser is nullptr");
104 return referenceParser_->GetGopLayerInfo(gopId, gopLayerInfo);
105 }
106
LoadPluginFile(const std::string & path)107 void *ReferenceParserManager::LoadPluginFile(const std::string &path)
108 {
109 FALSE_RETURN_V_MSG_E(path.length() > 0, nullptr, "Path is invalid");
110 auto ptr = ::dlopen(path.c_str(), RTLD_NOW | RTLD_LOCAL);
111 if (ptr == nullptr) {
112 MEDIA_LOG_E("Dlopen failed due to %{public}s", ::dlerror());
113 }
114 handler_ = ptr;
115 return ptr;
116 }
117
CheckSymbol(void * handler)118 bool ReferenceParserManager::CheckSymbol(void *handler)
119 {
120 if (handler) {
121 std::string createFuncName = "CreateRefParser";
122 std::string destroyFuncName = "DestroyRefParser";
123 CreateFunc createFunc = nullptr;
124 DestroyFunc destroyFunc = nullptr;
125 createFunc = (CreateFunc)(::dlsym(handler, createFuncName.c_str()));
126 destroyFunc = (DestroyFunc)(::dlsym(handler, destroyFuncName.c_str()));
127 if (createFunc && destroyFunc) {
128 MEDIA_LOG_D("CreateFuncName %{public}s", createFuncName.c_str());
129 MEDIA_LOG_D("DestroyFuncName %{public}s", destroyFuncName.c_str());
130 createFunc_ = createFunc;
131 destroyFunc_ = destroyFunc;
132 return true;
133 }
134 }
135 return false;
136 }
137 } // namespace Plugins
138 } // namespace Media
139 } // namespace OHOS