1 /*
2 * Copyright (C) 2023 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 "StreamParserManager"
17
18 #include "stream_parser_manager.h"
19 #include <dlfcn.h>
20 #include "common/log.h"
21
22 namespace {
23 const std::string HEVC_LIB_PATH = "libav_codec_hevc_parser.z.so";
24 const std::string VVC_LIB_PATH = "libav_codec_vvc_parser.z.so";
25 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_DEMUXER, "StreamParserManager" };
26 }
27
28 namespace OHOS {
29 namespace Media {
30 namespace Plugins {
31 std::mutex StreamParserManager::mtx_;
32 std::map<StreamType, void *> StreamParserManager::handlerMap_ {};
33 std::map<StreamType, CreateFunc> StreamParserManager::createFuncMap_ {};
34 std::map<StreamType, DestroyFunc> StreamParserManager::destroyFuncMap_ {};
35
StreamParserManager()36 StreamParserManager::StreamParserManager()
37 {
38 streamType_ = StreamType::HEVC;
39 }
40
~StreamParserManager()41 StreamParserManager::~StreamParserManager()
42 {
43 if (streamParser_) {
44 destroyFuncMap_[streamType_](streamParser_);
45 streamParser_ = nullptr;
46 }
47 }
48
Init(StreamType streamType)49 bool StreamParserManager::Init(StreamType streamType)
50 {
51 std::lock_guard<std::mutex> lock(mtx_);
52 if (handlerMap_.count(streamType) && createFuncMap_.count(streamType) && destroyFuncMap_.count(streamType)) {
53 return true;
54 }
55
56 std::string streamParserPath;
57 if (streamType == StreamType::HEVC) {
58 streamParserPath = HEVC_LIB_PATH;
59 } else if (streamType == StreamType::VVC) {
60 streamParserPath = VVC_LIB_PATH;
61 } else {
62 MEDIA_LOG_E("Unsupport stream parser type");
63 return false;
64 }
65 if (handlerMap_.count(streamType) == 0) {
66 handlerMap_[streamType] = LoadPluginFile(streamParserPath);
67 }
68 if (!CheckSymbol(handlerMap_[streamType], streamType)) {
69 MEDIA_LOG_E("Load stream parser failed");
70 return false;
71 }
72 return true;
73 }
74
Create(StreamType streamType)75 std::shared_ptr<StreamParserManager> StreamParserManager::Create(StreamType streamType)
76 {
77 MEDIA_LOG_D("Parser " PUBLIC_LOG_D32, streamType);
78 std::shared_ptr<StreamParserManager> loader = std::make_shared<StreamParserManager>();
79 if (!loader->Init(streamType)) {
80 return nullptr;
81 }
82 loader->streamParser_ = loader->createFuncMap_[streamType]();
83 if (!loader->streamParser_) {
84 MEDIA_LOG_E("CreateFunc_ failed");
85 return nullptr;
86 }
87 loader->streamType_ = streamType;
88 return loader;
89 }
90
ParseExtraData(const uint8_t * sample,int32_t size,uint8_t ** extraDataBuf,int32_t * extraDataSize)91 void StreamParserManager::ParseExtraData(const uint8_t *sample, int32_t size,
92 uint8_t **extraDataBuf, int32_t *extraDataSize)
93 {
94 FALSE_RETURN_MSG(streamParser_ != nullptr, "Stream parser is nullptr");
95 streamParser_->ParseExtraData(sample, size, extraDataBuf, extraDataSize);
96 }
97
IsHdrVivid()98 bool StreamParserManager::IsHdrVivid()
99 {
100 FALSE_RETURN_V_MSG_E(streamParser_ != nullptr, false, "Stream parser is nullptr");
101 return streamParser_->IsHdrVivid();
102 }
103
IsSyncFrame(const uint8_t * sample,int32_t size)104 bool StreamParserManager::IsSyncFrame(const uint8_t *sample, int32_t size)
105 {
106 FALSE_RETURN_V_MSG_E(streamParser_ != nullptr, false, "Stream parser is nullptr");
107 return streamParser_->IsSyncFrame(sample, size);
108 }
109
GetColorRange()110 bool StreamParserManager::GetColorRange()
111 {
112 FALSE_RETURN_V_MSG_E(streamParser_ != nullptr, false, "Stream parser is nullptr");
113 return streamParser_->GetColorRange();
114 }
115
GetColorPrimaries()116 uint8_t StreamParserManager::GetColorPrimaries()
117 {
118 FALSE_RETURN_V_MSG_E(streamParser_ != nullptr, 0, "Stream parser is nullptr");
119 return streamParser_->GetColorPrimaries();
120 }
121
GetColorTransfer()122 uint8_t StreamParserManager::GetColorTransfer()
123 {
124 FALSE_RETURN_V_MSG_E(streamParser_ != nullptr, 0, "Stream parser is nullptr");
125 return streamParser_->GetColorTransfer();
126 }
127
GetColorMatrixCoeff()128 uint8_t StreamParserManager::GetColorMatrixCoeff()
129 {
130 FALSE_RETURN_V_MSG_E(streamParser_ != nullptr, 0, "Stream parser is nullptr");
131 return streamParser_->GetColorMatrixCoeff();
132 }
133
GetProfileIdc()134 uint8_t StreamParserManager::GetProfileIdc()
135 {
136 FALSE_RETURN_V_MSG_E(streamParser_ != nullptr, 0, "Stream parser is nullptr");
137 return streamParser_->GetProfileIdc();
138 }
139
GetLevelIdc()140 uint8_t StreamParserManager::GetLevelIdc()
141 {
142 FALSE_RETURN_V_MSG_E(streamParser_ != nullptr, 0, "Stream parser is nullptr");
143 return streamParser_->GetLevelIdc();
144 }
145
GetChromaLocation()146 uint32_t StreamParserManager::GetChromaLocation()
147 {
148 FALSE_RETURN_V_MSG_E(streamParser_ != nullptr, 0, "Stream parser is nullptr");
149 return streamParser_->GetChromaLocation();
150 }
151
GetPicWidInLumaSamples()152 uint32_t StreamParserManager::GetPicWidInLumaSamples()
153 {
154 FALSE_RETURN_V_MSG_E(streamParser_ != nullptr, 0, "Stream parser is nullptr");
155 return streamParser_->GetPicWidInLumaSamples();
156 }
157
GetPicHetInLumaSamples()158 uint32_t StreamParserManager::GetPicHetInLumaSamples()
159 {
160 FALSE_RETURN_V_MSG_E(streamParser_ != nullptr, 0, "Stream parser is nullptr");
161 return streamParser_->GetPicHetInLumaSamples();
162 }
163
ConvertExtraDataToAnnexb(uint8_t * extraData,int32_t extraDataSize)164 bool StreamParserManager::ConvertExtraDataToAnnexb(uint8_t *extraData, int32_t extraDataSize)
165 {
166 FALSE_RETURN_V_MSG_E(streamParser_ != nullptr, false, "Stream parser is nullptr");
167 return streamParser_->ConvertExtraDataToAnnexb(extraData, extraDataSize);
168 }
169
ConvertPacketToAnnexb(uint8_t ** hvccPacket,int32_t & hvccPacketSize,uint8_t * sideData,size_t sideDataSize,bool isExtradata)170 void StreamParserManager::ConvertPacketToAnnexb(uint8_t **hvccPacket, int32_t &hvccPacketSize, uint8_t *sideData,
171 size_t sideDataSize, bool isExtradata)
172 {
173 FALSE_RETURN_MSG(streamParser_ != nullptr, "Stream parser is nullptr");
174 streamParser_->ConvertPacketToAnnexb(hvccPacket, hvccPacketSize, sideData, sideDataSize, isExtradata);
175 }
176
ParseAnnexbExtraData(const uint8_t * sample,int32_t size)177 void StreamParserManager::ParseAnnexbExtraData(const uint8_t *sample, int32_t size)
178 {
179 FALSE_RETURN_MSG(streamParser_ != nullptr, "Stream parser is nullptr");
180 streamParser_->ParseAnnexbExtraData(sample, size);
181 }
182
ResetXPSSendStatus()183 void StreamParserManager::ResetXPSSendStatus()
184 {
185 FALSE_RETURN_MSG(streamParser_ != nullptr, "Stream parser is nullptr");
186 streamParser_->ResetXPSSendStatus();
187 }
188
LoadPluginFile(const std::string & path)189 void *StreamParserManager::LoadPluginFile(const std::string &path)
190 {
191 auto ptr = ::dlopen(path.c_str(), RTLD_NOW | RTLD_LOCAL);
192 if (ptr == nullptr) {
193 MEDIA_LOG_E("Dlopen failed due to %{public}s", ::dlerror());
194 }
195 return ptr;
196 }
197
CheckSymbol(void * handler,StreamType streamType)198 bool StreamParserManager::CheckSymbol(void *handler, StreamType streamType)
199 {
200 if (handler) {
201 std::string createFuncName = "CreateStreamParser";
202 std::string destroyFuncName = "DestroyStreamParser";
203 CreateFunc createFunc = nullptr;
204 DestroyFunc destroyFunc = nullptr;
205 createFunc = (CreateFunc)(::dlsym(handler, createFuncName.c_str()));
206 destroyFunc = (DestroyFunc)(::dlsym(handler, destroyFuncName.c_str()));
207 if (createFunc && destroyFunc) {
208 MEDIA_LOG_D("CreateFuncName %{public}s", createFuncName.c_str());
209 MEDIA_LOG_D("DestroyFuncName %{public}s", destroyFuncName.c_str());
210 createFuncMap_[streamType] = createFunc;
211 destroyFuncMap_[streamType] = destroyFunc;
212 return true;
213 }
214 }
215 return false;
216 }
217 } // namespace Plugins
218 } // namespace Media
219 } // namespace OHOS